Tengo un archivo como este:
abc 123
abc 789
bcd 456
acb 135
Me gustaría imprimir la primera columna de la siguiente línea en la línea actual.
Salida deseada:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Prefiero usar awk.
Tengo un archivo como este:
abc 123
abc 789
bcd 456
acb 135
Me gustaría imprimir la primera columna de la siguiente línea en la línea actual.
Salida deseada:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
Prefiero usar awk.
Respuestas:
Memoriza la línea anterior:
awk 'NR > 1 { print prev, $1 } { prev = $0 } END { print prev }'
Esto procesa la entrada de la siguiente manera:
prev
, vea el siguiente paso) y el primer campo de la línea actual, separados por el separador de campo de salida (el carácter de espacio por defecto);prev
variable;awk
Enfoque alternativo :
$ awk 'NR == 1{printf "%s", $0;next}{printf " %s\n%s", $1,$0}' input.txt
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
La forma en que esto funciona es simple: la primera línea es un caso especial: la imprimimos sin nueva línea y le decimos a awk que pase a la siguiente línea sin ejecutar otros bloques de código. Después de eso, NR == 1{printf "%s", $0;next}
se omite, pero otras partes hacen el trabajo.
Recuerde que hasta ahora imprimimos una cadena formateada sin un nuevo carácter de línea. Por lo tanto, lo que se está haciendo printf " %s\n%s",$1,$0
ahora es la primera palabra impresa (y como no había nueva línea, permanece en la misma línea de salida), nueva línea insertada y luego toda la línea en sí (pero no termina con el carácter de nueva línea) . Por lo tanto, la siguiente primera palabra insertada permanecerá en la misma línea. El proceso continúa hasta que llegamos al final del archivo.
La posible mejora es incluir el END{print ""}
bloque para insertar la nueva línea final. En ciertos casos donde el archivo resultante será procesado por otros scripts, puede ser deseable.
Si bien el usuario solicitó AWK específicamente, el mismo enfoque con la impresión de cadenas formateadas se puede tomar con otros idiomas, por ejemplo Python. La alternativa de Python proporciona a aquellos curiosos acerca de cómo se puede implementar esto en otros idiomas:
#!/usr/bin/env python
from __future__ import print_function
import sys
old = None
for index,line in enumerate(sys.stdin):
if index == 0:
print(line.strip(),end=" ")
continue
words = line.strip().split()
print(words[0] + "\n" + line.strip(),end=" ")
Y uso así:
$ ./append_first.py < input.txt
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
La misma idea sobre la nueva línea final se aplica aquí.
Aquí hay una sed
manera fea solo por diversión
sed '2,$ s/[^ ]\+/& &/; 2,$ s/ /\n/' file | paste -d ' ' - -
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
2,$
desde la segunda línea hasta la últimas/[^ ]\+/& &/
duplicar el primer conjunto de caracteres que no son espacios en blanco;
separa comandos, como en el shells/ /\n/
reemplazar el primer espacio con una nueva líneapaste -d ' ' - -
pegue este desastre (agregue la segunda línea al tercero, la cuarta línea al tercero, etc.)sed
programas por diversión, entonces quizás deberías probar code-golf ;-)
En mi opinión, el enfoque más simple y legible es:
cut
)tail
)paste
)Ejemplo: su archivo inpult de muestra:
abc 123
abc 789
bcd 456
acb 135
Luego ejecute el siguiente comando en una terminal
cut -d' ' -f1 in.txt | tail -n +2 | paste -d' ' file -
Salida:
abc 123 abc
abc 789 bcd
bcd 456 acb
acb 135
La estructura detrás de esta solución difiere de las respuestas dadas. Sin necesidad de condiciones, bucles o expresiones regulares.
sed
solo sinpaste
:sed -r 'N;s/\n(\w+)/\1&/;P;D' somefile.txt