打印/Tee 到控制台,而不将输出传递到管道

打印/Tee 到控制台,而不将输出传递到管道

有没有办法将一个东西打印或发送到控制台,同时仍然将其他东西传递到下一个管道?就像是:

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 -; }

如果您需要消息(最终)出现在标准输出上,请更改revrev 2>&1或将管道括在大括号中:

{
    echo dog | 
    printOrWhatnot "PUTTING MY THING DOWN" | 
    sed 's/dog/cat/g' | 
    printOrWhatnot "FLIP IT" |
    rev
} 2>&1 

相关内容