bash - shell:将 grep 输出发送到 stderr 并保持 stdout 不变
问题描述
我有一个输出到的程序stdout
(实际上它输出到stderr
,但我可以轻松地将其重定向到stdout
with2>&1
或类似的。
我想grep
在程序的输出上运行,并将所有匹配项重定向到,stderr
同时保留不匹配的行stdout
(或者,我很乐意让所有行 - 而不仅仅是不匹配的行 - on stdout
)
例如
$ myprogram() {
cat <<EOF
one line
a line with an error
another line
EOF
}
$ myprogram | greptostderr error >/dev/null
a line with an error
$ myprogram | greptostderr error 2>/dev/null
one line
another line
$
一个简单的解决方案是:
myprogram | tee logfile
grep error logfile 1>&2
rm logfile
但是,我宁愿stderr
在它们发生时得到匹配的行,而不是在程序退出时......
最终,我找到了这个,这给了我一个 POSIX 解决方案的提示,如下所示:
greptostderr() {
while read LINE; do
echo $LINE
echo $LINE | grep -- "$@" 1>&2
done
}
无论出于何种原因,这不会输出任何内容(可能是缓冲问题)。
一个看起来有点难看的解决方案是这样的:
greptostderr() {
while read LINE; do
echo $LINE
echo $LINE | grep -- "$@" | tee /dev/stderr >/dev/null
done
}
有没有更好的方法来实现这一点?
理想情况下,我正在寻找一个 POSIX shell 解决方案,但bash
也很好......
解决方案
我会使用awk
而不是grep
,它可以让您更灵活地处理匹配和不匹配的行。
myprogram | awk -v p=error '{ print > ($0 ~ p ? "/dev/stderr" : "/dev/stdout")}'
每一行都会被打印出来;的结果$0 ~ p
确定该行是打印到标准错误还是标准输出。(您可能需要根据您的文件系统调整输出文件名。)
推荐阅读
- python - 我们可以创建一个具有相邻列的矩阵吗?
- rest - REST API:在单个查询中创建嵌套资源
- typescript - Loopback4 - 绑定时的身份验证 JWT 服务错误
- javascript - 如何使用复选框添加 IF 块
- python - Spotify API 从名称中查找艺术家 ID?
- c++ - 永无止境的文件读取循环(C++)
- r - 用希腊(即 LaTeX)符号替换图例标签/文本
- python - Pandas 以特殊字符分隔的分组和求和数据列
- javascript - Google App Script 中是否有不同的 Javascript 对象?
- javascript - 用鼠标单击捕获元素后取消放置事件