さまざまなコマンドでパイプラインデータを再利用する

さまざまなコマンドでパイプラインデータを再利用する

さまざまなアプリケーションに同じパイプラインを使用したいです。たとえば、次のようになります。

cat my_file | {
  cmd1
  cmd2
  cmd3
}

Cmd1は入力の一部を消費する必要があります。 Cmd2は他の部分を消費しなければなりません。

ただし、各コマンドはより多くの入力を消費するため、読み取った内容を適切にバッファリングする必要があります。

たとえば、

yes | nl | { 
  head -n 10 > /dev/null
  cat 
} | head -n 10

11行ではなく912行から出力されます。

Teeは、各コマンドが標準入力の一部を消費する必要があるため、良い選択ではありません。

動作させる簡単な方法はありますか?

ベストアンサー1

teeストリーム全体を処理するためにコマンドをコピーするために使用できるいくつかのコマンドがあります。

( ( seq 1 10 | tee /dev/fd/5 | sed s/^/line..\ / >&4 ) 5>&1 | wc -l ) 4>&1 
line.. 1
line.. 2
line.. 3
line.. 4
line.. 5
line.. 6
line.. 7
line.. 8
line.. 9
line.. 10
10

または、bashを使用して1行ずつ分割します。

while read line ;do
    echo cmd1 $line
    read line && echo cmd2 $line
    read line && echo cmd3 $line
  done < <(seq 1 10)
cmd1 1
cmd2 2
cmd3 3
cmd1 4
cmd2 5
cmd3 6
cmd1 7
cmd2 8
cmd3 9
cmd1 10

最後に実行する方法があり、cmd1cmd2cmd3だけフローの3分の1標準入力:

( ( ( seq 1 10 |
         tee /dev/fd/5 /dev/fd/6 |
           sed -ne '1{:a;p;N;N;N;s/^.*\n//;ta;}' |
           cmd1 >&4
     ) 5>&1 |
       sed -ne '2{:a;p;N;N;N;s/^.*\n//;ta;}' |
       cmd2 >&4
  ) 6>&1 |
    sed -ne '3{:a;p;N;N;N;s/^.*\n//;ta;}' |
    cmd3 >&4
) 4>&1 
command_1: 1
command_1: 4
command_1: 7
command_1: 10
Command-2: 2
Command-2: 5
Command-2: 8
command 3: 3
command 3: 6
command 3: 9

これを試すには、次のものを使用できます。

alias cmd1='sed -e "s/^/command_1: /"' \
    cmd2='sed -e "s/^/Command_2: /"' \
    cmd3='sed -e "s/^/Command_3: /"'

同じスクリプトで別のプロセスでストリームを使用したい場合は、次のことができます。

(
    for ((i=(RANDOM&7);i--;));do
        read line;
        echo CMD1 $line
      done
    for ((i=RANDOM&7;i--;));do
        read line
        echo CMD2 $line
      done
    while read line ;do
        echo CMD3 $line
      done
)
CMD1 1
CMD1 2
CMD1 3
CMD2 4
CMD2 5
CMD2 6
CMD2 7
CMD2 8
CMD2 9
CMD3 10

これを行うには、別のスクリプトを次のように変換する必要があります。バッシュ機能モノリシックスクリプトを書く能力。

別のアプローチは、各スクリプトが何も出力しないようにすることです。標準出力catチェーンそれらを:

#!/bin/sh

for ((i=1;1<n;i++));do
   read line
   pRoCeSS the $line
   echo >output_log
 done

cat

最終的なコマンドは次のとおりです。

seq 1 10 | cmd1 | cmd2 | cmd2

おすすめ記事