我们想要 grep 包含一些固定字符串的相应文件,然后仅以 ls -l 格式输出这些文件。
例如:
A) 以下方法使用多个 -exec 输出 grep 和 ls -l。
#
#
# find /usr/bin -type f -exec grep -Eil '#\!\/usr\/bin\/csh' {} \; -exec ls -l {} \; >scripts_csh_list 2>&1
#
#
#
# cat scripts_csh_list
/usr/bin/which
-r-xr-xr-x 1 bin bin 1191 Sep 06 2007 /usr/bin/which
#
#
B) 但我们希望仅使用 ls -l ... 获得更好的方法输出,然后通过 sh -c 'grep ... {}' 失败
注意:find -exec 的以下所有不同组合命令 ..输出相同的失败结果。
#
#
# find /usr/bin -type f -exec sh -c 'grep -Eil '\/usr\/bin\/csh' {} && ls -ltr {}' \; >scripts_csh_list 2>&1t
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c ' grep -Eil '\/usr\/bin\/csh' {} ' \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
# find /usr/bin -type f -exec sh -c ' grep -Eil '\/usr\/bin\/csh' "{}" ' \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c " grep -Eil '\/usr\/bin\/csh' {} " \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
#
# find /usr/bin -type f -exec sh -c " grep -Eil '\/usr\/bin\/csh' {} " \; >scripts_csh_list 2>&1
#
#
# tail -6 scripts_csh_list
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
grep: 0652-033 Cannot open {}.
#
#
答案1
原文中有很多看似不必要的引用和转义。虽然我在 中没有任何csh
脚本/usr/bin
,但我能够通过以下方式找到bash
脚本并获得ls
您似乎想要的输出:
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; -exec ls -l {} \; 2> /dev/null
(我通过在没有第二个的情况下运行来验证这一点-exec
,例如,
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; 2> /dev/null
并检查结果。)
对于稍微不同的输出列表,您也可以这样做
find /usr/bin -type f -exec grep -q '#!/usr/bin/bash' {} \; -ls 2> /dev/null
其中find
直接统计每个匹配文件本身,并返回ls
类似的结果。
我将错误通过管道传输只是为了/dev/null
在测试时使内容更具可读性;出于类似的原因,我没有将输出通过管道传输到文件。
请注意,我使用的bash
是我的 shell,因此将grep
表达式用单引号 ( '...'
) 括起来足以防止对其内容进行任何解释(并不是有太多需要担心的,正斜杠 ( /
) 对于 shell 来说并不特殊,在至少对于 bash 来说不是这样,如果您使用具有不同引用规则的 shell,YMMV。
至于该命令,除非您使用该-o
选项,否则find
会将AND
所有条件结合在一起,因此该命令仅在通过检查的ls -l
常规文件(您包含的文件)上运行。正如您的问题的评论中所指出的,可能会做您想要的事情,这只是确定有问题的文件 ( ) 是否匹配。type f
grep
grep -q
{}
编辑:正如评论中所述,如果用户的 shell 是csh
,则他们需要在表达式!
中转义grep
:'#\!/usr/bin/bash'
应该可以工作。
答案2
sh -c 'grep ... '
最后我们通过with命令做了以下正确的方法find -exec
。谢谢大家!
# find /usr/bin -type f -exec sh -c ' grep -q ''\#'\!/usr/bin/csh' "$1" && ls -l "$1" ' sh {} \; >scripts_csh_list 2>&1
# head -3 scripts_csh_list
-r-xr-xr-x 1 bin bin 1191 Sep 06 2007 /usr/bin/which