同じ行数のファイルが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
とにかくより良くて簡単です。
どのように動作しますか?
このスクリプトにはlineの出力である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)
}