将find和grep组合成一个命令

时间:2015-04-09 21:38:23

标签: bash shell

如何在不更改第一行的情况下将下面两行合并为一行?

 # find / -name sshd_config -print
 # grep -I <sshd_config path>  permitrootlogin

我想出了以下内容,但不知道我是否在不同情况下给出了正确的结果

cat `find / -name sshd_config -print` |grep permitrootlogin

4 个答案:

答案 0 :(得分:5)

不要cat $(...) [$()是反对的现代替代品] - 如果您的文件名包含特殊字符(空格,通配符等),则无法可靠地工作

相反,告诉find为您调用cat,并尽可能多地传递给每个cat调用的文件名:

find / -name sshd_config -exec cat -- '{}' + | grep permitrootlogin

......或者更好的是,完全忽略cat,只是将文件名传递给grep

find / -name sshd_config -exec grep -h -e permitrootlogin -- /dev/null '{}' +

如果您希望显示文件名,请将-h替换为-H

答案 1 :(得分:2)

你可以这样做:

find / -name "somefilename" -print0 | xargs -0 grep "something"

&#39; xargs&#39; keyword将把stdout转换为grep可以读取的参数。

答案 2 :(得分:0)

我猜你想要的是使用find / -name sshd_config -print的输出(应该是sshd_config文件的路径)并将其用作grep的第二个参数(这样就可以了为您的搜索字符串解析sshd_config文件。)

有几种方法可以实现这一目标。

后引号(`)中的命令被其输出替换。所以

grep permitrootlogin `find / -name sshd_config -print`

将替换为

grep permitrootlogin /path/to/the/sshd_config

会搜索/path/to/the/sshd_config permitrootlogin

也是如此
grep permitrootlogin $(find / -name sshd_config -print)

正如another answer已经提到的那样,这种语法比后面的方法有一些优势。也就是说,它可以嵌套。

但是,当找到文件的路径包含空格时,这仍会遇到问题。由于反引号和$(...)只执行文本替换,因此这样的补丁将作为多个参数传递给grep,每个参数可能都是无效路径。 (/path/to the/sshd_config将成为/path/tothe/sshd_config。)

不要使用花哨的引用和转义策略解决这个问题,请记住,UNIX命令已经设计为通常通过管道组合使用。确实find有一个-print0操作,它会将找到的文件的路径分隔\0,以便可以将它们与包含空格的路径区分开来。唉,grep无法处理零分隔的文件列表,仍希望文件作为调用参数进行搜索,而不是stdin

这是xargs发挥作用的地方。它将stdin上的内容应用为其他命令的参数。使用-0选项,它将stdin解释为零分隔列表,而不是将空格视为分隔符。

所以

find / -name sshd_config -print0 | xargs -0 grep permitrootlogin

应该让你满意。

答案 3 :(得分:-1)

|是一个管道,这意味着cat找到/ -name sshd_config -print``的标准输出将转到grep permitrootlogin的标准输入,所以你只需要确定输出是什么第一个命令