2012-06-09 58 views
1

考慮下面的示例Bash單行,其中按順序將單詞「hello」中的字母「h」,「e」和「o」按順序刪除。只剩下兩個「l」字母;如何在沒有循環的連續轉換管道中顯示每個步驟的結果?

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

我試圖找到用於顯示每個命令的輸出到一個套內屏幕的方法,以便其他人運行它可以看到正在發生的事情。繼續上面的例子,我想輸出如下;

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

這可能嗎?根據上面的單行操作,我們將命令輸出帶到垂直管道。所以我假設我不得不從管道打印到stdout,然後中斷我寫的「命令鏈」。 或者 tee可以在這裏使用,但我似乎無法實現慾望的影響。 更新tee將無法​​正常工作,因爲它的輸出仍然在管道的邊界內,杜!

非常感謝。

回答

6

終端上這僅適用於:

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

/dev/tty設備輸出重定向到當前終端,無論正常輸出在哪裏。

+0

這正是我需要的,謝謝! – jwbensley

0

您可以使用tee --代表控制檯:

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

希望這有助於!

EDIT

將該溶液WILL NOT WORK因爲stdout被封閉,通過該通過的stdout裝置產生輸出的所有命令重複使用。

我不會刪除答案,因爲它明確指出它不能解決問題,但同時顯示這種解決方案不是有效的,爲什麼。如果有人發現自己處於相同的情況,會發現這些信息,這將會很有用。

+0

奇怪的是,這不像預期的那樣工作; '回聲「你好」| tee - | tr -d h | tr -d e | tr -d o'輸出「ll ll」,所以它的最終輸出,但靠近開始?! – jwbensley

+0

在'tee'內仍然使用'-' +1 :) – jwbensley

+0

奇怪!我會稍微查看一下,並嘗試變化。 –

0

但這WILL工作:

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 

我找不到更好的解決方案。

+0

請注意,這將殺死所有的並行性,這對於大數據塊可能是有問題的。如果你沒有迴應「你好」,但1TB文件,你有麻煩;) – bitmask

+0

對,但我認爲並非如此:消息是「你好」,操作是一個字母替換... –

+0

無需過程替換:'tmp = $ {tmp // h}'等。 – chepner

0

你可以通過在其上聽一個FIFO(或一個普通文件)做到這一點:

mkfifo tmp.fifo 
tail -f tmp.fifo 

然後,只需在一個單獨的shell中運行你的命令:

echo hello | tee -a tmp.fifo | tr -d e | tee -a tmp.fifo | tr -d o 
2

用小一點loop:

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

The。僅用於簡短的解決方案。更仔細地閱讀的問題後,我測試後發現,它的工作原理在管道鏈太:

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 
+0

你也可以用參數擴展替換'tr':'w = $ {w // $ c}'從'$ w'中刪除所有出現的'$ c'。 – chepner

+0

@chepner:是的,因爲它是純粹的bash,所以我把它包括進去了。 –

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 

$$是Shell的PID。

+0

請注意,這取決於具有'/ proc'文件系統的系統,這對於Linux系統來說幾乎肯定是正確的,但不適用於Mac OS X. – chepner

+0

'/ dev/tty'有什麼問題? –

+0

很棒的建議,/ dev/tty更好,但這仍然是一個很好的答案,謝謝! – jwbensley

3

IMO,如果這是真實世界的問題,而不是怎麼可能在bash做,然後,而不是bash的瘋狂啓動X TR和Y三通過程,你可以嘗試一個簡單的Perl oneliner:

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 
0

房多一個?

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 
[email protected]:~$ ello 
llo 
ll 

一點說服力脅迫要求通過[email protected]:~$

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

輸出以消除腐敗:

hello 
ello 
llo 
ll 
+0

短一行 - 如果'prompt'爲null沒有腐蝕性強制是必要的 - 儘可能少? – ekim

+0

「沒有燈光,沒有車,沒有一個豪華它是原始的,可以」 - 完全通用的標準IO甚至沒有控制檯'-' – ekim

相關問題