find
mais grep
Combine find
para percorrer diretórios recursivamente com grep
.
Se o suporte para -print0
e -0
for compilado, você poderá usar xargs
para invocar grep
para muitos arquivos de uma vez¹:
find /some/dir -type f -print0 | xargs -0 grep -H PATTERN
Se os nomes de seus arquivos forem simples (sem espaço em branco ou \'"
), você não precisará de -print0
/ -0
:
find /some/dir -type f |xargs grep -H PATTERN
Se você não tiver xargs
adequado, precisará invocar grep
em cada nome de arquivo separadamente:
find /some/dir -type f -exec grep -H PATTERN {} \;
Se você tem find
, mas não tem -exec
, e seus nomes de arquivo são domesticados (sem novas linhas ou \[*?
), e seu shell suporta substituições de comandos (ou seja, ash e não hush) e não são muitos arquivos para considerar, você pode gerar a lista de nomes de arquivos com find
e passar isso como um argumento para grep
.
set -f
IFS='
'
grep PATTERN $(find /some/dir -type f)
set +f
Se houver muitos arquivos, você poderá usar um loop for
sobre todos os arquivos (ainda assim, somente cinza, devido à substituição do comando).
set -f
IFS='
'
for x in $(find /some/dir -type f); do
grep -H PATTERN "$x"
done
set +f
¹ Não -exec … +
no Busybox.
Sem find
Se você não tem find
, fica complicado. Se o seu Busybox tem cinza e um test
decente, você pode escrever uma travessia de diretório recursiva no 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
Mas se você não tem find
, provavelmente você está em um sistema muito limitado onde o shell é silencioso, o qual não possui funções. Você pode simular funções com eval
. Eu suponho que você tenha test
; se você não fizer isso, é possível detectar diretórios, mas é doloroso.
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"