find
加 grep
组合find
以递归遍历目录grep
。
如果支持-print0
和-0
已编译,那么您可以使用xargs
来一次调用grep
多个文件¹:
find /some/dir -type f -print0 | xargs -0 grep -H PATTERN
Run Code Online (Sandbox Code Playgroud)
如果您的文件名是温和的(没有空格或\'"
),则不需要-print0
/ -0
:
find /some/dir -type f |xargs grep -H PATTERN
Run Code Online (Sandbox Code Playgroud)
如果没有合适的xargs
,则需要分别调用grep
每个文件名:
find /some/dir -type f -exec grep -H PATTERN {} \;
Run Code Online (Sandbox Code Playgroud)
如果您有find
但没有-exec
,并且您的文件名是温和的(没有换行符或\[*?
),并且您的 shell 支持命令替换(即 ash 而不是 hush),并且没有太多文件需要考虑,您可以生成文件名列表,find
并将其作为参数传递给grep
.
set -f
IFS='
'
grep PATTERN $(find /some/dir -type f)
set +f
Run Code Online (Sandbox Code Playgroud)
如果有很多文件,您可以for
对所有文件使用循环(由于命令替换,仍然是 ash-only)。
set -f
IFS='
'
for x in $(find /some/dir -type f); do
grep -H PATTERN "$x"
done
set +f
Run Code Online (Sandbox Code Playgroud)
¹在 Busybox 上没有-exec … +
。
find
如果你没有find
,它会变得复杂。如果你的 Busybox 有 ash 和一个像样的test
,你可以在 shell 中编写递归目录遍历。
traverse () {
d=$1; shift
for x in "$d"/* "$d"/.[!.]* "$d"/..?*; do
if test -f "$x"; then
"$@" "$x"
elif test -d "$x"; then
traverse "$x" "$@"
fi
done
}
traverse /some/dir
Run Code Online (Sandbox Code Playgroud)
但是,如果您没有find
,则您可能在一个非常有限的系统上,其中外壳是静默的,缺乏功能。您可以使用eval
. 我假设你有test
;如果你不这样做,检测目录是可能的,但很痛苦。
command='grep -H PATTERN'
traverse='
for x in "$d"/* "$d"/.[!.]* "$d"/..?*; do
if test -f "$x"; then
'"$command"' "$x"
elif test -d "$x"; then
d="$x"
eval "$traverse"
fi
done
'
d=/some/dir
eval "$traverse"
Run Code Online (Sandbox Code Playgroud)