Tenemos la mejor respuesta que hemos encontrado on line. Deseamos que te sirva de ayuda y si deseas aportar algo que nos pueda ayudar a mejorar hazlo libremente.
Solución:
%
es el operador módulo (ver https://en.wikipedia.org/wiki/Modulo_operation) y NR%3?FS:RS
es una expresión ternaria (ver https://en.wikipedia.org/wiki/%3F:). Ambas son construcciones comunes en muchos lenguajes de programación, no son específicas de awk. Para conocer el significado de ORS, NR, FS y RS, consulte la página de manual de awk.
Ejecute esto para ver los valores de las variables en el código antes y después del comando que está ejecutando:
$ cat tst.awk
BEGIN
printf "%s="%s"n", "RS", RS
printf "%s="%s"n", "FS", FS
printf "---n"
printf "%s="%s"n", "$0", $0
printf "%s="%s"n", "NR", NR
printf "%s="%s"n", "NR%3", NR%3
printf "before) %s="%s"n", "ORS", ORS
ORS = (NR%3 ? FS : RS)
printf "after) %s="%s"n", "ORS", ORS
.
$ awk -f tst.awk file
RS="
"
FS=" "
---
$0="1"
NR="1"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="2"
NR="2"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="3"
NR="3"
NR%3="0"
before) ORS=" "
after) ORS="
"
---
$0="4"
NR="4"
NR%3="1"
before) ORS="
"
after) ORS=" "
---
$0="5"
NR="5"
NR%3="2"
before) ORS=" "
after) ORS=" "
---
$0="6"
NR="6"
NR%3="0"
before) ORS=" "
after) ORS="
"
Observe en qué números de línea de entrada (NR
) el separador de registros de salida (ORS
) se convierte en una nueva línea (como RS
) frente a un carácter en blanco (como FS
).
Una forma más detallada de escribir el mismo código sería:
$ cat tst.awk
if (NR%3 == 0)
ORS = "n"
else
ORS = " "
print
$ awk -f tst.awk file
1 2 3
4 5 6
y FYI, la forma correcta (más robusta y más clara) de escribir el código idiomático conciso intentado en su pregunta sería:
awk 'ORS=(NR%3?FS:RS)1'
Los paréntesis alrededor del ternario se requieren en algunos awks en algunos contextos y siempre mejoran la legibilidad, así que utilícelos siempre. El código original se basa en el resultado de la asignación a ORS que produce un no-null/valor distinto de cero para que sea un true condición y así invocar la acción predeterminada de awks de imprimir el registro actual. Solo use el resultado de una acción en ese contexto cuando NECESITE hacerlo; de lo contrario, lo morderá un día cuando sus datos no sean exactamente lo que esperaba. En lugar de dejar la tarea en un bloque de condición, la moví a un bloque de acción y luego agregué una constante true condición después, 1
para garantizar que todos los registros se impriman independientemente de los resultados de esa asignación.
No la awk
explicación ya que ya tienes más de una buena respuesta, pero alternativas para la misma tarea
$ seq 6 | xargs -n3
1 2 3
4 5 6
$ seq 6 | paste - - -
1 2 3
4 5 6
con paste
el delimitador predeterminado es la pestaña, que puede cambiar a espacio con -d' '
$ seq 6 | pr -3ats' '
1 2 3
4 5 6
Si tienes alguna sospecha y forma de ascender nuestro crónica puedes añadir una reseña y con deseo lo ojearemos.