5

如果我有一个过程a.out,我可以./a.out | grep foo看到由 foo 过滤的 a.out 的标准输出。我也可以说./a.out 2>&1 | grep foo看到 err 和 out 被 foo 过滤。使用该tee命令,我可以将标准输出发送到终端和可能的文件输出。但是有没有办法单独过滤它们?如:

./a.out | tee grep foo file.txt

但是这样file.txt过滤到的内容与 foo 匹配,但与我在屏幕上看到的不匹配……或者甚至更好的是,我在屏幕上看到的内容被 baz 而不是 foo 过滤?如果在 bash 中没有办法这样做,我会写我自己的“tee”,但我想有一些方法......

4

3 回答 3

3

非常简单,只需对文件句柄使用进程替换:

./a.out | tee >(grep foo > out.txt) | grep baz

另请注意,它tee可以采用任意数量的参数,因此您可以执行以下操作:

./a.out | tee >(grep foo > foo.txt) >(grep bar > bar.txt) [etc]
于 2012-08-30T21:42:54.850 回答
3

要将所有内容显示到终端,并将输出过滤到文件,请尝试:

./a.out| tee /dev/tty | grep foo > file

如果您使用的是带有 /proc 文件系统的系统(例如 linux),您可以使用以下命令过滤到终端的输出:

{ ./a.out | tee /proc/self/fd/3 | grep foo > file; } 3>&1 | grep bar

但即便如此,也可能工作太辛苦了。只需这样做:

./a.out | awk '/foo/{ print > "file" } 1' | grep bar
于 2012-08-30T20:58:04.027 回答
2
{ { ( myCommandThatOutputsOnStdOutandStdErr; ) \
| ( awk ' ... filters stdout ... ' - ; ) >&3; } 2>&1 \
| ( awk ' ... filters stderr ... ' - ; ) >&4; } 3>&1 4>&2

这是伪代码。awk 简介不是真实的,但可以用您自己的过滤器替换。这个想法是两个单独的过滤器可以独立地对 stderr 和 stdout 进行操作,但将未在 stdout 上过滤的内容留在 stdout 上,将未在 stderr 上过滤的内容留在 stderr 上。

最后的3>&1and4>&2也可以很容易地变成3>my.stdoutand 4>my.stderr

于 2012-08-30T21:04:59.420 回答