No estoy muy seguro de por qué esto tiene 87 votos a favor, ciertamente se puede mejorar con un ejemplo al menos.
Arj
Probablemente porque la pregunta es extremadamente simple por naturaleza y fácil de entender sin un ejemplo, lo cual es raro, pero en este caso parece funcionar. El problema aquí no es la falta de información, creo, sino más bien muestra una falta de investigación independiente.
DryLabRebel
Esta pregunta también es un duplicado de esta pregunta.
Necesita una coma, ya que hoy somos exigentes: el espacio concatena los campos, la coma los separa en una declaración de impresión. Eso fusionará los dos campos
Solo para agregar al comentario anterior, el problema con el uso '{print $x,"\t",$y}'es que awk interpreta cada variable separada por comas como su propio campo, por lo que el resultado será en realidad field1<space><tab><space>field2, (porque usará el delimitador de espacios en blanco de forma predeterminada) en lugar de lo field1<tab>field2que probablemente sea lo que estás esperando. usar el Separador de campo de salida (OFS) es casi siempre lo que desea.
DryLabRebel
13
awk '{print $NF-1, $NF}' inputfile
Nota: esto solo funciona si existen al menos dos columnas. En registros con una columna obtendrá un falso"-1 column1"
Prueba y verás. Funciona Solaris 9 awk & nawk. La alternativa es $ (NF-1)
jim mcnamara
1
@coaddict: supongo que no ha trabajado con diferentes implementaciones de awk. Se han presentado (quizás erróneamente) comportamientos antiguos de awks. No tengo la boca abierta para probar, que es probablemente a lo que te refieres. Así que no sé con certeza por qué su comentario fue incorrecto. Linux awk listo para usar generalmente es boquiabierto. Lo probaré y lo publicaré. Mientras tanto, pruebe con Soalris o HPUX o DGX o lo que sea para ver lo que quiero decir con awk antiguo.
jim mcnamara
6
Probablemente te engañaron para que pensaras que funcionó porque lo intentaste echo 1 2 3 | awk .... $NF-1está ($NF) - 1en cada awkimplementación.
Stephane Chazelas
El código fuente de "One True Awk" tiene más de 40 conflictos en la yaccgramática, lo cual es irónico dado lo que la A significa en awk. ¿Diferentes versiones de awk analizando las cosas de manera diferente? ¡Gran sorpresa!
Kaz
1
@THESorcerer, intente con echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'- o cualquier otra entrada donde el segundo último campo no sea uno menos que el último campo.
Glenn Jackman
6
@jim mcnamara: intente usar paréntesis para alrededor NF, es decir, $(NF-1)y en $(NF)lugar de $NF-1y $NF(funciona en Mac OS X 10.6.8 para FreeBSD awky gawk).
echo '
1 2
2 3
one
one two three
'| gawk '{if (NF >= 2) print $(NF-1), $(NF);}'# output:# 1 2# 2 3# two three
Ya habíamos considerado () antes. Pensé que estábamos discutiendo de dónde provenía el antiguo comportamiento awk original.
jim mcnamara
+1 para una respuesta con explícito $(NF-1), que al menos es más portátil que $NF-1; definitivamente es menos ambiguo. $(NF)Sin embargo, es exagerado, solo $NFservirá. También vale la pena protegerse contra las líneas con menos de 2 columnas, ya que con las líneas de una columna obtendría el valor de la primera columna dos veces , y con las líneas de columna cero, es decir, vacías, el comando awk fallaría por completo, debido a un intento para acceder a un campo con índice -1.
mklement0
1
el uso de gawk presenta el problema:
gawk '{ print $NF-1, $NF}' filename
1223-1 one
-1 three
# cat filename1223
one
one two three
Acabo de poner boquiabierto a Solaris 10 M4000: Entonces, gawk es el cuplrit en el problema de $ NF-1 vs. $ (NF-1). Siguiente pregunta ¿qué dice POSIX? por:
Las primeras 2 líneas de su archivo de entrada de muestra no son útiles porque producen la misma salida con cualquier comportamiento. ¿Puede volver a confirmar que Solaris awk NO se comporta como gawk en este caso?
mklement0
En cuanto a su enlace a la especificación awk: el argumento anecdótico para usar $(NF-1)es que los dos ejemplos de cálculo del índice de campo en la especificación usan esa forma: $(NF-1)y $(NF+2). Luego está la sección "Expresiones en awk", que $exprtiene una precedencia [mucho] mayor que expr - expr. Dado que NFes una expresión en sí misma, $NF-1debería evaluarse como ($NF)-1. Incluso SI, después de todo, existen implementaciones de awk que evalúan $NF-1como $(NF-1), la lección aprendida aquí es que usar $(NF-1)es la opción segura y portátil.
Respuestas:
Puede hacer uso de la variable
NF
que se establece en el número total de campos en el registro de entrada:esto supone que tiene al menos 2 campos.
fuente
awk '{print $(NF-1) "\t" $NF}' file
oawk '{print $(NF-1), $NF}' file
oawk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file
.'{print $x,"\t",$y}'
es que awk interpreta cada variable separada por comas como su propio campo, por lo que el resultado será en realidadfield1<space><tab><space>field2
, (porque usará el delimitador de espacios en blanco de forma predeterminada) en lugar de lofield1<tab>field2
que probablemente sea lo que estás esperando. usar el Separador de campo de salida (OFS) es casi siempre lo que desea.Nota: esto solo funciona si existen al menos dos columnas. En registros con una columna obtendrá un falso
"-1 column1"
fuente
echo 1 2 3 | awk ...
.$NF-1
está($NF) - 1
en cadaawk
implementación.yacc
gramática, lo cual es irónico dado lo que la A significa en awk. ¿Diferentes versiones de awk analizando las cosas de manera diferente? ¡Gran sorpresa!echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}'
- o cualquier otra entrada donde el segundo último campo no sea uno menos que el último campo.@jim mcnamara: intente usar paréntesis para alrededor
NF
, es decir,$(NF-1)
y en$(NF)
lugar de$NF-1
y$NF
(funciona en Mac OS X 10.6.8 para FreeBSDawk
ygawk
).fuente
$(NF-1)
, que al menos es más portátil que$NF-1
; definitivamente es menos ambiguo.$(NF)
Sin embargo, es exagerado, solo$NF
servirá. También vale la pena protegerse contra las líneas con menos de 2 columnas, ya que con las líneas de una columna obtendría el valor de la primera columna dos veces , y con las líneas de columna cero, es decir, vacías, el comando awk fallaría por completo, debido a un intento para acceder a un campo con índice -1.el uso de gawk presenta el problema:
Acabo de poner boquiabierto a Solaris 10 M4000: Entonces, gawk es el cuplrit en el problema de $ NF-1 vs. $ (NF-1). Siguiente pregunta ¿qué dice POSIX? por:
No hay dirección en un sentido u otro. No está bien. gawk implica resta, otros awks implican número de campo o resta. hmm.
fuente
$(NF-1)
es que los dos ejemplos de cálculo del índice de campo en la especificación usan esa forma:$(NF-1)
y$(NF+2)
. Luego está la sección "Expresiones en awk", que$expr
tiene una precedencia [mucho] mayor queexpr - expr
. Dado queNF
es una expresión en sí misma,$NF-1
debería evaluarse como($NF)-1
. Incluso SI, después de todo, existen implementaciones de awk que evalúan$NF-1
como$(NF-1)
, la lección aprendida aquí es que usar$(NF-1)
es la opción segura y portátil.prueba con esto
fuente
Pruebe esto para tener en cuenta todos los escenarios posibles:
o
o
fuente