Tengo un archivo que se parece a esto:
AE United Arab Emirates
AG Antigua & Barbuda
AN Netherlands Antilles
AS American Samoa
BA Bosnia and Herzegovina
BF Burkina Faso
BN Brunei Darussalam
Y me gustaría invertir el orden, imprimiendo primero todo excepto $ 1 y luego $ 1:
United Arab Emirates AE
¿Cómo puedo hacer el truco "todo excepto el campo 1"?
Respuestas:
Asignando
$1
obras pero dejará un espacio de protagonismo:awk '{first = $1; $1 = ""; print $0, first; }'
También puede encontrar el número de columnas
NF
y usarlo en un ciclo.fuente
awk {'first = $1; $1=""; print $0'}|sed 's/^ //g'
$1=""
deja un espacio como lo mencionó Ben Jackson, así que use unfor
bucle:Entonces, si su cadena fue "uno dos tres", la salida será:
dos
tres
Si desea el resultado en una fila, puede hacer lo siguiente:
Esto le dará: "dos tres"
fuente
awk '{for(i=2;i<=NF;i++){ printf("%s",( (i>2) ? OFS : "" ) $i) } ; print ;}'
que: imprime los campos 2 a NF, agrega el Separador de campos de salida según sea necesario (es decir, excepto antes de $ 2). La última impresión agrega una nueva línea final para finalizar la impresión de la línea actual. Ese funcionará si cambia FS / OFS (es decir, no siempre será "espacio")Utilice el
cut
comando con la--complement
opción:fuente
echo a b c | cut -d' ' -f 2-
es una alternativaQuizás la forma más concisa:
Explicación:
$(NF+1)=$1
: Generador de un último campo "nuevo".$1=""
: Establece el primer campo original en nulosub(FS,"")
: Después de las dos primeras acciones,{$(NF+1)=$1;$1=""}
elimine el primer separador de campo usando sub. La impresión final está implícita.fuente
Elimine el primer campo y el separador, e imprima el resultado (
7
es un valor distinto de cero, por lo que imprime $ 0).fuente
1
? Me pregunto el uso de este patrón y quería entenderlo. ¡Gracias!Establecer el primer campo en
""
deja una única copia deOFS
al comienzo de$0
. Suponiendo queOFS
es solo un carácter (por defecto, es un solo espacio), podemos eliminarlo consubstr($0, 2)
. Luego agregamos la copia guardada de$1
.fuente
Si está abierto a una solución de Perl ...
es una solución simple con un separador de entrada / salida de un espacio, que produce:
Este siguiente es un poco más complejo.
y asume que el separador de entrada / salida tiene dos espacios:
Se utilizan estas opciones de la línea de comandos:
-n
bucle alrededor de cada línea del archivo de entrada, no imprima automáticamente cada línea-l
elimina las nuevas líneas antes del procesamiento y las vuelve a agregar después-a
modo de división automática: divide las líneas de entrada en la matriz @F. Predeterminado para dividir en espacios en blanco-F
modificador autosplit, en este ejemplo se divide en '' (dos espacios)-e
ejecutar el siguiente código de Perl@F
es la matriz de palabras en cada línea, indexada comenzando con 0$#F
es el número de palabras en@F
@F[1..$#F]
es una parte de la matriz del elemento 1 hasta el último elemento@F[1..$#F,0]
es una parte de la matriz del elemento 1 hasta el último elemento más el elemento 0fuente
El separador de campo en gawk (al menos) puede ser una cadena y un carácter (también puede ser una expresión regular). Si sus datos son consistentes, esto funcionará:
Son dos espacios entre las comillas dobles.
fuente
awk '{ tmp = $1; sub(/^[^ ]+ +/, ""); print $0, tmp }'
fuente
Muevamos todos los registros al siguiente y establezcamos el último como el primero:
Explicación
a=$1
guarde el primer valor en una variable temporal.for (i=2; i<=NF; i++) $(i-1)=$i
guarde el valor del campo N en el campo (N-1).$NF=a
guarde el primer valor ($1
) en el último campo.{}1
verdadera condición para hacerawk
que la acción predeterminada:{print $0}
.De esta manera, si tiene otro separador de campo, el resultado también es bueno:
fuente
Un primer intento parece funcionar para su caso particular.
fuente
Opción 1
Existe una solución que funciona con algunas versiones de awk:
Explicación:
Resultado:
Sin embargo, eso podría fallar con versiones anteriores de awk.
opcion 2
Es decir:
Tenga en cuenta que lo que debe borrarse es el OFS, no el FS. La línea se vuelve a calcular cuando se asigna el campo $ 1. Eso cambia todas las ejecuciones de FS a una OFS.
Pero incluso esa opción aún falla con varios delimitadores, como se muestra claramente al cambiar el OFS:
Esa línea dará como resultado:
Eso revela que las ejecuciones de FS se están cambiando a una OFS.
La única forma de evitarlo es evitar el recálculo del campo.
Una función que puede evitar volver a calcular es sub.
El primer campo podría capturarse, luego eliminarse de $ 0 con sub, y luego volver a imprimir ambos.
Opción 3
Incluso si cambiamos el FS, el OFS y / o agregamos más delimitadores, funciona.
Si el archivo de entrada se cambia a:
Y el comando cambia a:
La salida será (aún conservando los delimitadores):
El comando podría expandirse a varios campos, pero solo con awks modernos y con la opción --re-interval activa. Este comando en el archivo original:
Producirá esto:
fuente
Si está abierto a otra solución de Perl:
fuente
También hay una opción sed ...
Explicado...
Explicado más a fondo ...
fuente
Otra forma más ...
... esto vuelve a unir los campos 2 a NF con el FS y genera una línea por línea de entrada
Utilizo esto con git para ver qué archivos se han modificado en mi directorio de trabajo:
fuente
Otra forma fácil de usar el comando cat
fuente