Une siete archivos con awk línea por línea

Une siete archivos con awk línea por línea

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, pastees mejor y más sencillo de todos modos.

Cómo funciona

En este script ahay 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 ial 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

    FNRes el número de línea del archivo actual que estamos leyendo y $0es el contenido de esa línea. Este código se suma $0al final de a[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, si FNR==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)
}

información relacionada