web-dev-qa-db-ja.com

印刷の出力をawkの複数のファイルにリダイレクトする

同じ行を2つの異なるファイルに出力したい。私が今やっていることは:

print ID[i]" "Value[i]" "TS1[i]" "TS2[i] > "file1.txt";
print ID[i]" "Value[i]" "TS1[i]" "TS2[i] > "file2.txt";

1つのコマンドを記述して、2つの異なるファイルにリダイレクトできますか?

[〜#〜]編集[〜#〜]

コマンド出力全体を複数のファイルに出力したくありません。いくつかの条件に基づいていくつかのレコードを複数のファイルに書き込みたいのですが、これをawkスクリプト内に出力するため、効率的それを行う方法。

8
Aashu

awkではできません。

teeを使用すると、次のようなことができます。

$ awk '{print ID[i]" "Value[i]" "TS1[i]" "TS2[i]}' file | tee out1 out2

既存のファイルを上書きする代わりに追加したい場合は、tee -aを使用します。

出力全体を印刷したくない場合は、以下を試すことができます。

awk '
    BEGIN {outfile["a.txt"];outfile["b.txt"]}
    { for (file in outfile) { print > file } }' file
11
cuonglm

awk内では、_print "text" > "file"_を使用してファイルにリダイレクトする代わりに、次を使用してコマンドにリダイレクトできます。

_print "something" | "tee file1.txt file2.txt"
_

最初にその_|_を使用すると、awkはコマンドを生成し、次に同じコマンドを再利用するため、実行するたびに新しいteeを開始しませんこれはファイルを上書きしません(次回awkで新しいコマンドを開始する場合は、close("tee file1.txt file2.txt")を呼び出す必要があります)。ただし、_> "file1.txt"_と_| "tee file1.txt..."_の両方を実行すると、競合が発生します。

次に、代わりに_>> "file1.txt"_および_| "tee -a file1.txt..."_を使用できます。

ただし、 @ cuonglmのforアプローチ を使用するか、awk関数を使用すると、よりクリーンで効率的になります。

10

ユーザー定義関数 を使用すると、コードがきれいになり、重複が少なくなります(それが問題である場合)。

function print_to_files( message, file_a, file_b ) {
   print message > file_a;
   print message > file_b;
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message , "filea", "fileb" );'

それが必要な場合は、ファイルをハードコーディングします。

function print_to_files( message ) {
   print message > "/path/to/filea";
   print message > "/path/to/fileb";
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message );'
4
Matt

これはsedを使用して行うことができますが、入力を明確に理解していないと、具体的にどのように示すかわかりません。それでも、ここに一般的な例があります:

seq 10 | sed -ne '/1/w ./onesfile.txt' -e '/3/w threesfile.txt'

これは、1onesfile.txtを含む行のみを書き込み、それ以外の場合は3に書き込みます。それ以外はすべて削除されます。これはveryこれがどのように機能するかを示す基本的な例ですが、サンプル入力を提供できれば、もう少しうまくいくかもしれません。

sedが書き込み用にファイルを開くと、プロセスが完了するまで開いたままになります-自身の書き込みが継続的に切り捨てられることはありません-ファイル記述子は、プロセスの存続期間中保持されます。

3
mikeserv