有没有办法将一个东西打印或发送到控制台,同时仍然将其他东西传递到下一个管道?就像是:
echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev
这将导致:
PUTTING MY THING DOWN
FLIP IT
tac
编辑:这也应该适用于多行输入:
printOrWhatNot() {...}
seq 10 30 |printOrWhatNot searching for 3s | grep 3
会输出
searching for 3s
13
23
30
Lars 的回答似乎只传递了第一个输入(这里是10
)
另外,理想情况下,输出会在处理过程中内联,这不是我在格伦的答案中看到的。所以
seq 10 30 |tee /dev/tty |printOrWhatNot searching for 3s | grep 3
将有助于:
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
searching for 3s
13
23
30
答案1
我不知道有任何用于此目的的标准命令,但是用一个小 shell 脚本编写您自己的命令很容易。创建以下内容,使其可执行,并将其位置添加到您的 PATH 中。
编辑-- 更新以处理多行标准输入,并处理输入中的空格。
打印或其他什么:
#!/bin/bash
# printOrWhatnot script, to re-pipe stdin, while echoing something else via stderr
# read stdin (possibly multi-lined) into $my_array[]:
while read -t 1 piped
do
my_array=("${my_array[@]}" "$piped")
done
# echo the supplied arguments by sending them to stderr:
echo "$@" 1>&2
# now spew $my_array[], line by line, to any further processing:
arrayLen=${#my_array[@]}
for (( i=0; i<$arrayLen; i++ ));
do
echo ${my_array[$i]}
done
现在它应该按照您的建议工作:
myhost> echo dog | printOrWhatnot "PUTTING MY THING DOWN" | sed 's/dog/cat/g' | printOrWhatnot "FLIP IT"|rev
PUTTING MY THING DOWN
FLIP IT
tac
答案2
您需要将消息发送到与 stdout 不同的文件描述符,然后将 stdin 转储到 stdout 不变:
printOrWhatnot() { echo "$@" >&2; cat -; }
如果您需要消息(最终)出现在标准输出上,请更改rev
为rev 2>&1
或将管道括在大括号中:
{
echo dog |
printOrWhatnot "PUTTING MY THING DOWN" |
sed 's/dog/cat/g' |
printOrWhatnot "FLIP IT" |
rev
} 2>&1