Bash:複数のファイルを繰り返し、各ファイルの各行を印刷して別のファイルに書き込みます。

Bash:複数のファイルを繰り返し、各ファイルの各行を印刷して別のファイルに書き込みます。

行数が異なる3つのファイルがあります。 3つのファイルを繰り返しながら、各ファイルの最初の行を新しいファイルoutput1.txtとして印刷し、各ファイルの2行目を別の新しいファイルoutput2.txtとして印刷しようとしています。各ファイルには行数が異なるため、file2 と file3 のエントリを持たない複数の行がある場合は、それを無視して、後で生成される出力ファイルに何も印刷しないでください。 Bashでどのようにこれを達成できますか?

ファイル1

xyz
abc
def
ghi
jkl

ファイル2

123
456
789

ファイル3

ax1
by2

結果ファイル

出力1.txt

xyz
123
ax1

出力2.txt

abc
456
by2

出力3.txt

def
789

出力4.txt

ghi

出力5.txt

jkl

ベストアンサー1

bashこれを行うには、Tellを使用してくださいawk。これが bash の目的です(たとえば、テキスト処理自体を実行する代わりに)。

たとえば、次のawk 1行ステートメントは、FNRリテラル文字列「output」、現在の入力ファイルの現在の行番号(awk変数)、およびリテラル文字列「.txt」で構成されるファイル名に各入力行を書き込みます。

$ awk '{print > "output" FNR ".txt"}' file*

$ tail output*
==> output1.txt <==
xyz
123
ax1

==> output2.txt <==
abc
456
by2

==> output3.txt <==
def
789

==> output4.txt <==
ghi

==> output5.txt <==
jkl

注:出力ファイルの数が多い(数百以上)、問題が発生する可能性があります。一部のバージョンのawkでは、カーネルお​​よびログイン環境でプロセスに許可されているファイルハンドルの数を超えると、プロセスがエラーで終了する可能性があります。異なるバージョンのawk(GNU awkなど)を使用すると、特定の瞬間に書き込み用に開いているファイルハンドルを管理するときに遅くなる可能性があります。入力ファイルの一部が数百行の長さでない限り、これは問題ではありません。

以下は、すべてのバージョンのawkとすべての長さの入力ファイルで動作しますが(一度に書き込むために1つの出力ファイルのみを開くため)、はるかに遅くなります。なぜなら各書き込みの出力ファイルを開き、書き込み後すぐに閉じます。それにもかかわらず、シェルで実行するよりも数倍速いです。

awk '{
  # use 5-digit zero-padded output filenames for this version
  # e.g. output00001.txt
  out = sprintf("output%05i.txt", FNR);

  if (out in files) {
    # we have written to this file before, so append to it
    print >> out
  } else {
    # first write to this file, so create or truncate it.
    print > out
    files[out]=1
  }
  close(out)
}' file*

おすすめ記事