将多个unix命令合并为一个输出


9

我需要在我们的邮件日志中搜索特定的电子邮件地址。我们将一个名为maillog的当前文件以及一个星期的.bz2文件保存在同一文件夹中。当前,我正在运行以下命令来搜索文件:

grep person@domain.com maillog
bzgrep person@domain.com *.bz2

有没有一种方法可以将grepbzgrep命令组合为单个输出?这样,我可以将合并的结果通过管道发送到单个电子邮件或单个文件。

Answers:


24

另一种方法是

{ grep ...; bzgrep ...;} >file

&&遇到的困难是,bzgrep如果grep失败,将无法运行。

请注意最后一条命令后的大括号和分号后的必需空格。另外,您可以使用subshel​​l语法(用括号代替大括号),但语法不那么严格:

(grep ...; bzgrep ...) >file

+1是解决此问题的最佳通用Shell方法。Shell分组是通常未充分利用的功能。
Phil Hollenback

2
你不是要()代替{}吗?
Ehtesh Choudhury 2012年

在arch linux上,它可以工作,()但不能用{}+1的方式,因为这是我需要的!
克里斯·马格努森

11

如果文件未经bzip压缩,则bzgrep自动默认为常规grep。因此,以下内容就足够了:

bzgrep person@domain.com maillog *bz2 | mail -s "logs yay" someuser@blah

哦,当然,这也是我的强制性GNU Parallel解决方案:

parallel -m bzgrep person@domain.com ::: maillog* *bz2 | mail -s "logs yay" someuser@blah

如果您要检查大量文件,这可能会更快。


2

这是另一种方式(假设您正在运行bash,而您可能正在运行):

cat <(bzgrep ...) <(grep ...)

在这里,bash将bzgrep和grep命令的输出透明地馈送到cat中,就好像它们是文件一样(它们在后台,URL的详细信息位于底部)。

在您的特殊情况下,我建议您使用Phil的解决方案,但以上是将其保存在您包中的一个好技巧。

如果您有兴趣,可以在这里阅读更多信息:http : //www.tldp.org/LDP/abs/html/process-sub.html


是的,关于“如何区分两个过程的输出”的标准答案。一个好窍门。
Phil Hollenback

1

在撰写本文时,大多数(如果不是全部)Bourne派生的shell(包括)都接受了答案的语法bash。我建议在顶部进行编辑并接受答案,以解决此问题,但我也倾向于添加所有其他信息,而这更多的是重写而不是编辑。

您可以使用复合命令:

{ grep ...; bzgrep ...; } >file

..或子外壳(请注意括号而不是花括号):

(grep ...; bzgrep ...) >file

..将命令分组。subshel​​l方式具有更好的语法(更宽容的缺少空格,允许您省略最后一个分号),但是它要么派生一个新进程,要么通过在清理后的环境中运行命令来“假装”。两者都有优点,这取决于您想做什么,在这里无关紧要,但是如果您想更加熟练地使用Shell,那么值得一试。

注意:您也可以将流水线与这些技巧一起使用,因此您可以执行以下操作:

{ grep ...; bzgrep ...; } | less

PS:如果您不在乎组合输出中的匹配顺序,则可以&在两个命令之间使用一个,例如:{ grep ... & bzgrep ...; }。然后,这两个命令同时运行:grep启动并外壳将其放在后台,然后外壳将运行bzgrep。(但是有一个小警告,涉及文件重定向和文件流缓冲的解释可能会导致输出文件中很小一部分的行被拆分/缠结:您是否会看到这取决于您的方式grepbzgreplibc stdio.h功能被实现。在大多数实现,我相信重定向到一个文件将避免这个问题,所以你可以做之前管道命令{ foo & bar; } | cat - >file作为一种解决方法。)


0

您可以将命令与&&绑定在一起,这将允许您运行每个命令。

您还可以在每个命令的末尾添加>> textfile.txt,并让输出命中一个文件,然后将该文件邮寄出去。


2
正如geekosaur所提到的,在这里不应该使用&&,因为grep的返回值取决于它是否找到了东西。如果您这样做了grep ... && bzgrep ...,如果grep没有命中,它将返回失败并且命令将停止。 >>与不同>,这是个好主意,它将输出添加到现有文件的末尾。
DerfK 2011年

对,我已经忘记了阻止第二条命令的退出条件。
迈克,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.