Use o grep para encontrar todos os arquivos em um diretório com duas cadeias de caracteres [duplicado]

20

Estou tentando descobrir a sintaxe correta para encontrar duas strings, a parte inteira de cada string, em qualquer lugar (não precisa estar perto uma da outra) em um arquivo. Portanto, qualquer arquivo que tenha tanto foo quanto o número 321 , não precisa estar sozinho e pode ser uma substring correspondente. Eu tentei o seguinte sem muita sorte:

grep 'foo\|321' *

grep 'foo|321'
    
por imaginative 14.03.2013 / 21:46

5 respostas

15

Você pode fazer isso com um script curto:

for FILE in *
do
  grep -q foo $FILE && grep -q 321 $FILE && echo $FILE
done

Você também pode fazer isso em uma linha:

for FILE in *; do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE; done

grep retorna 0 (verdadeiro) se encontrou a string e o && separando os comandos significa que a segunda só será executada se a primeira for verdadeira. A opção -q garante que grep não produza nada.

O eco só será executado se ambas as seqüências forem encontradas no mesmo arquivo.

Eu pensei em uma maneira diferente de fazer isso. Desta forma, provavelmente será mais eficiente se os arquivos em questão forem maiores do que a sua RAM instalada, pois só tem que grep através de cada arquivo uma vez.

 for FILE in *
 do
   test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE
 done

e a versão de uma linha:

 for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
    
por 14.03.2013 / 23:07
14

GNU grep

Deve ser um pouco mais rápido porque o segundo grep pode operar em uma lista de arquivos.

grep -lZ 'foo' * | xargs -0 grep -l '321'

POSIX grep com find

find é mais útil se você quiser pesquisar diretórios recursivos (nesse caso, perderá as opções -mindepth e -maxdepth .

find . -mindepth 1 -maxdepth 1 -type f -exec grep -q 'foo' {} \; -exec grep -l '321' {} +
    
por 15.03.2013 / 02:44
2

Estranho. Para mim, as duas variantes funcionam (grep (GNU grep) 2.13):

grep 'foo\|321'
grep -E 'foo|321'

Editar 1 - exibe arquivos apenas com as duas correspondências

A resposta for file in * funciona, mas pode se tornar um pesadelo de desempenho (para grandes quantidades de arquivos): pelo menos dois processos por arquivo. Isso é mais rápido (no mundo GNU):

find . -type f -print0 | xargs -0 -r grep --files-with-matches --null -- string1 |
  xargs -0 -r grep --files-with-matches -- string2

string1 deve ser o que resulta em menos correspondências.

    
por 14.03.2013 / 22:23
1

Basicamente, para encontrar todos os arquivos, incluindo uma string específica em um diretório, você pode usar:

grep -lir "pattern" /path/to/the/dir
  • -l : para que essa varredura pare na primeira correspondência
  • -i : para ignorar distinções de maiúsculas e minúsculas no padrão e na entrada arquivos
  • -r : procura todos os arquivos no diretório, recursivamente

Para pesquisar dois padrões, tente o seguinte:

grep -lr "321" $(grep -lr "foo" /path/to/the/dir)
    
por 15.03.2013 / 04:31
-1

deve ser

grep -e "foo" -e "321" *

Use -e para vários padrões

EDITAR

Caso você precise combinar os dois:

grep -e ".*foo.*321.*" *

Se o pedido não importa:

grep -e ".*foo.*321.*" ".*321.*foo.*" *
    
por 14.03.2013 / 21:49

Tags