1

次の例のBashワンライナーを考えてみましょう。この例では、「h」、「e」、「o」の文字が「hello」という単語から一度に1つずつこの順序で削除されています。2つの「l」文字だけが残ります。

$ echo "hello" | tr -d h | tr -d e | tr -d o
ll

各コマンドの出力を1つのライナー内の画面に表示して、それを実行している他の人が何が起こっているかを確認できるようにする方法を見つけようとしています。上記の例を続けて、次のように出力したいと思います。

$ echo "hello" | tr -d h | tr -d e | tr -d o
hello
ello
llo
ll

これは可能ですか?上記のワンライナーの操作に従って、コマンドからコマンドへの出力を垂直パイプで運んでいます。したがって、stdoutに出力するには、パイプから切り離す必要があると思います。これにより、作成した「コマンドチェーン」が中断されます。またはtee、ここで使用できるかもしれませんが、欲求効果を達成できないようです。 更新tee出力がまだパイプの境界内にあるため、機能しません。

どうもありがとう。

4

8 に答える 8

6

これは端末でのみ機能します。

echo hello  | tee /dev/tty |
    tr -d h | tee /dev/tty |
    tr -d e | tee /dev/tty |
    tr -d o

/dev/ttyデバイスは、通常の出力がどこに行くかに関係なく、出力を現在の端末にリダイレクトします。

于 2012-06-09T13:12:31.690 に答える
4

teeターミナルに直接出力できます。

echo hello  | tee /proc/$$/fd/1 |
    tr -d h | tee /proc/$$/fd/1 |
    tr -d e | tee /proc/$$/fd/1 |
    tr -d o

$$シェルのPIDです。

于 2012-06-09T13:12:59.800 に答える
3

IMO、これが現実世界の問題であり、bashでどのように実行できるかではない場合、XtrおよびYteeプロセスを開始するbashの狂気の代わりに、単純なperlワンライナーを試すことができます。

echo hello | perl -nale 'foreach $i (qw(h e o)) {@F=map{s/$i//g;print $_;$_}@F}'

印刷されます:

ello
llo
ll

または、本当にbashが必要な場合(@chepnerが提案したように)

echo "hello" | while read w; do for c in h e o; do w=${w//$c};echo $w; done;done

また

while read w; do for c in h e o; do w=${w//$c};echo $w; done;done < wordlist
于 2012-06-09T14:14:36.837 に答える
2

小さな小さなループで:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done

。簡単な解決策にのみ使用されます。質問をもっと注意深く読んだ後、私はテストして、それがパイプチェーンでも機能することを発見しました:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done | less 
# pure bash buildins, see chepner's comment
w="hello" ; for c in h e o .; do echo $w; w=${w/$c}; done
于 2012-06-09T12:56:02.103 に答える
0

しかし、これは機能します:

tmp=`echo "hello"`; echo $tmp; tmp=`echo $tmp | tr -d h`; echo $tmp; tmp=`echo $tmp | tr -d e`; echo $tmp; echo $C | tr -d o

それは醜いですが、それは動作します。このソリューションでは、各パスを格納する変数を作成し、それらすべてを表示します。

tmp=`echo "hello"`
echo $tmp
tmp=`echo $tmp | tr -d h`
echo $tmp
tmp=`echo $tmp | tr -d e`
echo $tmp
echo $C | tr -d o

より良い解決策を見つけることができません。

于 2012-06-09T12:48:53.027 に答える
0

あなたが聞くfifo(または通常のファイル)を使用してそれを行うことができます:

mkfifo tmp.fifo
tail -f tmp.fifo

次に、別のシェルでコマンドを実行します。

echo hello | tee -a tmp.fifo | tr -d e | tee -a tmp.fifo | tr -d o
于 2012-06-09T12:51:43.947 に答える
0

もう1つの部屋?

echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) )

また

 echo "hello" | 
tee >(tr -d h | 
tee >(tr -d e | 
tee >(tr -d o  ) ) ) 

出力は次のとおりです。

hello
ubuntu@ubuntu:~$ ello
llo
ll

による腐敗を排除するには、少し説得力のある強制が必要です。ubuntu@ubuntu:~$

cat <(echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) ) )

出力は次のとおりです。

hello
ello
llo
ll
于 2013-03-08T05:49:11.680 に答える
0

コンソールを表すtee -として使用できます。-

echo "hello" | tee - | tr -d h | tee - | tr -d e | tee - | tr -d o

お役に立てば幸いです。

編集

によって出力を生成するすべてのコマンドによってブロックされて再利用されるため、このソリューションは機能しませんstdoutstdout

問題が解決しないことが明確に示されているため、回答を削除しませんが、この種の解決策は無効であり、その理由も示しています。誰かが同じ状況にいることに気付いた場合、この情報を発見するでしょう、そしてそれは役に立ちます。

于 2012-06-09T12:28:28.717 に答える