Como grep um texto recursivamente no BusyBox 1.0?

3

Como posso encontrar um arquivo contendo uma certa string em um BusyBox 1.0, se grep -r não funcionar?

    
por Gilles 25.01.2012 / 10:05

1 resposta

6

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"
    
por 27.01.2012 / 18:55