考虑以下示例 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