我想要一个命令行命令来在文件系统中搜索特定单词的所有 shell 脚本,所以我在工作中四处询问并得到以下解决方案:
grep word `find / -name \*.sh 2>/dev/null`
find / -name "*.sh" 2>/dev/null | xargs grep word
Run Code Online (Sandbox Code Playgroud)
但是,我对命令行不太熟悉,因此这两种解决方案对我来说似乎都不透明。我更喜欢做一些看起来像的事情:
ls -r *.sh | cat | grep -H word
Run Code Online (Sandbox Code Playgroud)
但是似乎您无法将文件名通过管道传输到 cat (至少我认为这就是问题所在)。
什么是最清晰的解决方案?其次,最有效的解决方案是什么?
编辑:我需要知道在哪个文件中找到了这个词,以便我可以修改脚本。
编辑:如果您有 GNU 实用程序,请参阅Gilles对使用 GNUgrep
递归能力的方法的回答,该方法比该find
方法简单得多。如果您只想显示文件名,您仍然需要添加-l
我在下面描述的选项。
使用grep -l word
仅打印包含匹配文件名。
如果要查找文件系统中所有以 结尾.sh
、从根开始的文件/
,那么find
是最合适的工具。
最便携和最有效的建议是:
find / -type f -name '*.sh' -exec grep -l word {} + 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
这与它的可读性差不多,如果您了解每个组件背后的语义,则不难解析。
find /
:find
从文件系统根目录开始运行,/
-type f
: 只匹配常规文件-name '*.sh'
: ... 并且只匹配名称以 .sh
-exec ... {} +
:...
在组中匹配的文件上运行指定的命令,其中{}
由组中的文件名替换。这个想法是在系统限制内一次对尽可能多的文件运行命令 ( ARG_MAX
)。{} +
表单的效率来自...
通过最大化传递给每次调用的文件数来最小化必须调用命令的次数...
。grep -l word {}
:与上面{}
的相同{}
,并由文件名替换。如前所述,grep -l
打印包含匹配的文件的名称word
。2>/dev/null
:隐藏错误消息(从技术上讲,将标准错误重定向到黑洞/dev/null
)。这是为了美观和现实的原因,因为在运行find
上/
可能会导致你可能不关心,而您没有权限读取的文件和目录,你没有权限遍历“权限被拒绝”的消息的投注。您在问题中收到和发布的建议存在一些问题。两个都
grep word `find / -name \*.sh 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
和
find / -name "*.sh" 2>/dev/null | xargs grep word
Run Code Online (Sandbox Code Playgroud)
在名称中包含空格的文件上失败。最好避免将文件名完全放在命令替换中。第一个有可能遇到 ARG_MAX 限制的额外问题。第二个接近我的建议,但没有充分的理由在xargs
这里使用,更不用说安全和正确使用 的xargs
需要牺牲某些仅限 GNU 的选项的可移植性 ( find -print0 | xargs -0
)。
在非嵌入式 Linux、Cygwin 或其他带有GNU grep 的系统上,在FreeBSD 上,在NetBSD和OSX 上:
grep -r --include='*.sh' word .
Run Code Online (Sandbox Code Playgroud)
不要解析ls
. 并且不要在 的输出上使用命令替换find
,正如jw013 所解释的。
归档时间: |
|
查看次数: |
18858 次 |
最近记录: |