Как сказал steeldriver, разумный способ сделать это - 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
Но если вы должны использовать 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
Сценарий awk хранит все данные в памяти. Если файлы большие, это может стать проблемой. Но, для этой задачи, paste
в любом случае лучше и проще.
В этом скрипте a
- массив, а a[i]
- вывод для строки i
. По мере чтения каждого из последующих файлов мы добавляем новую информацию для строки i
в конец a[i]
. После завершения чтения файлов мы выводим значения в a
. Более подробно:
a[FNR]=a[FNR](FNR==NR?"":";"")$0
FNR
- это номер строки текущего файла, который мы читаем, а $0
- содержимое этой строки. Этот код добавляет $0
в конец a[FNR]
. Если мы все еще читаем первый файл, то перед $0
ставится точка с запятой. Это делается с помощью сложного троичного оператора: (FNR==NR?"":";")
. На самом деле это просто команда if-then-else. Если мы читаем первый файл, то есть если FNR==NR
, то она возвращает пустую строку """
. Если нет, то возвращается точка с запятой, ;
.
END{for (i=1;i<=FNR;i++) print a[i]}
После завершения чтения всех файлов выводит данные, которые мы накопили в массиве a
.