Respuestas:
La -F
opción necesita un argumento: -F,
por ejemplo.
El final del awk
script debe separarse con un (espacio de caracteres) con el resto de los parámetros.
Si el separador de campo es ,
y desea conservarlo, y si el número de columna es constante e inferior o igual a 11, intente esto:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file
. Dicho esto, nueva versión de GNU awk
para apoyar esto: gawk -i inplace '{blah blah}' file
.
mv newfile file
que pueda usar cat newfile > file ; rm -f newfile
, esto preserva el inodo y los permisos de file
.
mktemp
nombres de archivos temporales en lugar de codificar en scripts. por ejemplotf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
La solución más corta sería
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
No estoy seguro de si ,+
funcionará en todas las awk
versiones, pero funciona al menos en GNU awk, también con el -c
modo de compatibilidad.
Explicación:
$(NF+1)=$7
: primero agregamos el séptimo campo al final de la línea (podría ser $12=$7
en este caso)$7=""
: en el siguiente paso se borra el séptimo campo (pero los delimitadores circundantes permanecen)$0=$0
) tratando múltiples comas como separador de campo (esto se hace vía -F',+'
, aquí +
significa una o más veces), y también reorganizar el registro actual $1=$1
para forzar la reconstrucción de la línea usando el campo de salida previamente establecido separador (establecido por una opción -v OFS=,
)1
Entrada de ejemplo:
1,2,3,4,5,6,7,8,9,10,11
salida
1,2,3,4,5,6,8,9,10,11,7
,+
debería funcionar.
all,ball,call,,,fall
→ all,ball,call,fall
). (2) $(NF+1)=$7
es un enfoque inteligente. En mi humilde opinión, $0 = $0 OFS $7
es un poco más claro, solo un par de caracteres más largos, y parece hacer lo mismo. ¿Puedes pensar en una situación en la que $0 = $0 OFS $7
no haga lo mismo que tu código?
$0=$0 OFS $7
es probablemente idéntico a $(NF+1)=$7
, pero solo con el resto del código sin cambios, no en general.
Si está imprimiendo con OFS=
, sin un separador entre los campos, simplemente puede guardar el valor de $7
en una variable, configurarlo $7
para vaciarlo e imprimir la línea y la variable directamente. No necesita especificar todos los campos:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Probablemente quieras decir:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awk
nunca ve las comillas simples OFS=''
, ¿verdad? También puede simplemente escribir OFS=
; Es exactamente lo mismo.
Usted no ha dicho específicamente que quería utilizar awk, y qué decir que quería utilizar la edición in situ como el proporcionado por sed -i
, por lo que aquí es una sed -i
variante. Por awk
lo general, es mejor trabajar con columnas, pero este es un caso en el que prefiero sed
, porque naturalmente maneja números arbitrarios de columnas.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Explicación:
-r
selecciona expresiones regulares extendidas para evitar muchas barras invertidasPor supuesto, esto no funcionará con archivos que ocultan comas entre comillas (o peor, escapen de ellas), pero awk tampoco lo manejará sin algunas acrobacias serias. Si tiene ese problema, sería mejor con el perl
módulo Text:CSV
o el python
módulo csv
.
Un par de awk
variantes (suponiendo que su archivo esté dentro de la variable $file
)
Aquí puede realizar un ciclo para todos los colores, imprimir con el separador de campo (OFS) e imprimir el terminador de registro (ORS) al final de la línea.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"
Aquí con el uso de una expresión regular y la gensub()
función
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
matando a la 7 ª campo y la impresión de que al final de la línea.
$0
es todo el registro $n
es el enésimo registro NF
es el número de campos de la línea actual OFS
el separador archivado de salidaORS
el terminador de registro de salida1
es el truco para decir a awk true
e imprimir el valor predeterminado ( $0
).Actualización ...
Casi me olvido, es posible cambiar todas las columnas después de la 7ma .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7
que sería más robusto que "," $7
. (2) Creo que eso ", " $7
está mal, en la medida en que la pregunta indica que el OP no quiere espacios después de las comas. (Y, si los datos de entrada tenían espacios después de las comas, entonces $7
sería ya comenzar con un espacio, y que estaría agregando un adicional.)
OFS $7
, no solo más robusto, sino aún más general ( "la prisa hace el desperdicio" )
^
indica la parte específica de la orden en el que se encuentra el error.