Tengo siete (u ocho, etc.) archivos con el mismo número de líneas.
archivo1
1.001
1.002
1.003
1.004
archivo2
2.001
2.002
2.003
2.004
archivo3
3.001
3.002
3.003
3.004
etc.
Salida deseada:
1.001;2.001;3.001;4.001;5.001;6.001;7.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004
¿Cómo hacerlo con script corto en awk?
Respuesta1
Como dijo Steeldriver, la forma razonable de hacerlo es con paste
:
$ paste -d';' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004
Pero, si debes usar awk
:
$ awk '{a[FNR]=a[FNR](FNR==NR?"":";")$0} END{for (i=1;i<=FNR;i++) print a[i]}' file*
1.001;2.001;3.001;4.001;5.001;6.001;7.001;8.001
1.002;2.002;3.002;4.002;5.002;6.002;7.002;8.002
1.003;2.003;3.003;4.003;5.003;6.003;7.003;8.003
1.004;2.004;3.004;4.004;5.004;6.004;7.004;8.004
El script awk mantiene todos los datos en la memoria. Si los archivos son grandes, esto podría ser un problema. Pero, para esta tarea, paste
es mejor y más sencillo de todos modos.
Cómo funciona
En este script a
hay una matriz que a[i]
es la salida de la línea i
. A medida que leemos cada uno de los archivos siguientes, agregamos la nueva línea de información i
al final de a[i]
. Una vez que hayamos terminado de leer los archivos, imprimimos los valores en formato a
. Con más detalle:
a[FNR]=a[FNR](FNR==NR?"":";")$0
FNR
es el número de línea del archivo actual que estamos leyendo y$0
es el contenido de esa línea. Este código se suma$0
al final dea[FNR]
. Excepto si todavía estamos leyendo el primer archivo, ponemos un punto y coma antes$0
. Esto se hace usando la declaración ternaria de aspecto complejo:(FNR==NR?"":";")
. En realidad, esto es solo un comando si-entonces-si no. Si estamos leyendo el primer archivo, es decir, siFNR==NR
, entonces devuelve una cadena vacía""
. Si no, devuelve un punto y coma;
.END{for (i=1;i<=FNR;i++) print a[i]}
Una vez que hayamos terminado de leer todos los archivos, esto imprimirá los datos que hemos acumulado en la matriz
a
.
Respuesta2
POSIX Awk; esto funciona con una cantidad arbitraria de archivos y los archivos ni siquiera tienen que tener la misma cantidad de líneas. El script continúa hasta que todos los archivos estén sin líneas:
BEGIN {
do {
br = ch = 0
while (++ch < ARGC)
if (getline < ARGV[ch]) {
printf ch < ARGC - 1 ? $0 ";" : $0 RS
br = 1
}
} while (br)
}