パイプを介してシェルの複数のファイルに接続する

パイプを介してシェルの複数のファイルに接続する

私は大量のデータを生成するアプリケーションを持っていますが、そのアプリケーションをディスクに保存したくありません。アプリケーションは主に使用したくないデータを出力しますが、別々のファイルに分割する必要がある有用な情報セットを出力します。たとえば、次のような出力が提供されます。

JUNK
JUNK
JUNK
JUNK
A 1
JUNK
B 5
C 1
JUNK

次のようにアプリケーションを3回実行できます。

./app | grep A > A.out
./app | grep B > B.out
./app | grep C > C.out

これは私が望むものを得るのに時間がかかるでしょう。また、すべての出力を単一のファイルにダンプして解析したくありません。

上記の3つのタスクを組み合わせてアプリケーションを一度だけ実行しても、3つの個別の出力ファイルを取得する方法はありますか?

答え1

お持ちの場合ティー

./app | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null

(からここ)

プロセス交換について)

答え2

あなたはそれを使用することができますawk

./app | awk '/A/{ print > "A.out"}; /B/{ print > "B.out"}; /C/{ print > "C.out"}'

答え3

シェルを使用することもできますパターンマッチング機能:

./app | while read line; do 
     [[ "$line" =~ A ]] && echo $line >> A.out; 
     [[ "$line" =~ B ]] && echo $line >> B.out; 
     [[ "$line" =~ C ]] && echo $line >> C.out; 
 done

でも:

./app | while read line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && echo $line >> "$foo".out; 
  done; done

次に始まるバックスラッシュと行を処理するより安全な方法-

./app | while IFS= read -r line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && printf -- "$line\n" >> "$foo".out; 
  done; done

@StephaneChazelasがコメントで指摘したように、これはあまり効率的ではありません。最良の解決策は次のとおりです。@AurélienOoms '

答え4

以下はPerl言語の1つです:

./app | perl -ne 'BEGIN {open(FDA, ">A.out") and 
                         open(FDB, ">B.out") and 
                         open(FDC, ">C.out") or die("Cannot open files: $!\n")} 
                  print FDA $_ if /A/; print FDB $_ if /B/; print FDC $_ if /C/'

関連情報