awkを使用して7つのファイルを1行ずつリンクします。

awkを使用して7つのファイルを1行ずつリンクします。

同じ行数のファイルが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]iia[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)
}

関連情報