同じ行数のファイルが 7 つ (または 8 つなど) あります。
ファイル1
1.001
1.002
1.003
1.004
ファイル2
2.001
2.002
2.003
2.004
ファイル3
3.001
3.002
3.003
3.004
等
望ましい出力:
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
awk の短いスクリプトでそれを実行するにはどうすればよいでしょうか?
答え1
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
。
答え2
POSIX Awk。これは任意の数のファイルで動作し、ファイルの行数が同じである必要もありません。スクリプトは、すべてのファイルの行数がなくなるまで続行されます。
BEGIN {
do {
br = ch = 0
while (++ch < ARGC)
if (getline < ARGV[ch]) {
printf ch < ARGC - 1 ? $0 ";" : $0 RS
br = 1
}
} while (br)
}