如何在不循环的情况下显示连续转换管道中每个步骤的结果



考虑以下示例 Bash 单行,其中字母"h"、"e"和"o"按该顺序从单词"hello"中一次删除一个。只剩下两个"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不起作用,因为它的输出仍在管道的边界内,呃!

非常感谢。

这仅适用于终端:

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

/dev/tty设备将输出重定向到当前端子,无论正常输出流向何处。

您可以将输出直接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。

IMO,如果这是现实世界的问题,而不是如何在 bash 中做到这一点,那么与其疯狂地启动 X tr 和 Y tee 进程,不如尝试一个简单的 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

有一个小循环:

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

但这起作用:

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

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

您可以使用您侦听的 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

您可以使用tee -作为-表示控制台:

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

希望有帮助!

编辑

此解决方案将不起作用,因为stdout被所有通过 stdout 产生输出的命令阻止和重用。

我不会删除答案,因为它清楚地表明它不能解决问题,但也表明这种解决方案是无效的以及为什么。如果有人发现自己处于同样的情况,就会发现这些信息,这将是有用的。

再留一个房间?

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

最新更新