Usando grep depois de usar find para obter os arquivos

4

Então eu sou relativamente novo na linha de comando. Consegui usar o find para obter uma saída de vários arquivos de vários diretórios, uma vez que não havia um local específico para isso (tenho certeza de que isso pode ser encurtado):

find ./ -name filename1.ext && find ./ -name filename2.ext && find ./ -name filename3.ext

Agora, isso me deu a lista do que eu estava querendo, mas agora que encontrei os arquivos em questão, quero enviá-los para obter informações.

    
por trazinaz 27.06.2018 / 19:08

5 respostas

6

Você pode agrupar todas as name primárias em uma única instrução de localização e, depois, encontrar grep de execução.

find . \( -name filename1.ext -o \
      -name filename2.ext -o \
      -name filename3.ext \) \
      -exec grep 'pattern' {} \;
    
por 27.06.2018 / 19:19
3

Tente isso,

find ./ -type f \( -name filename1.ext -o -name filename2.ext -o -name filename3.ext \) -exec grep 'string' {} \;
  • -type f desde que você está procurando por arquivos, é melhor especificar o tipo para obter o resultado mais rápido.

  • -o significa OR, permite que você adicione mais nomes de arquivos à pesquisa

por 27.06.2018 / 19:18
1

Além da resposta correta, está, de fato, usando -o e -exec , aqui está uma maneira geral de capturar a saída de um comando anterior e analisá-lo linha por linha

(find .... && find ... && cat ... && ls ... && ...) | while read line; do grep string $line; done
    
por 28.06.2018 / 11:19
0

Usando bash :

shopt -s globstar
grep 'pattern' ./**/filename[123].ext

Com a opção globstar shell ativada, o padrão ** se comporta como * , mas corresponde a / em nomes de caminho. Isso funcionará a menos que o padrão corresponda a milhares de arquivos; nesse caso, é provável que você receba um erro "Argument list too long" do shell. Isso também não verifica se os nomes dos caminhos correspondentes são para arquivos regulares ou não, como um find faria com seu teste -type f . Além disso. se o padrão não corresponder a qualquer coisa , ele permanecerá não expandido.

Em um loop, que resolve todos os três problemas mencionados acima:

shopt -s globstar
for pathname in ./**/filename[123].ext; do
    [ -f "$pathname" ] && grep 'pattern' /dev/null "$pathname"
done
    
por 27.06.2018 / 20:22
0

Em geral, existem pelo menos três maneiras de fazer uma combinação find + grep :

  1. grep padrão 'find dir especificadores de localização -print'
  2. find dir especificadores de localização -exec grep padrão {} \;
  3. find dir especificadores de localização -print | xargs grep padrão

E, claro, não há nada de especial sobre grep aqui; esses mesmos três padrões podem ser usados para find mais qualquer comando.

O número 1 é, em certo sentido, a maneira mais antiga e básica, já que os quadros de retorno sempre foram a maneira de capturar a saída de um comando e usá-lo na linha de comando de outro. (Nos dias de hoje, tenho a impressão de que há uma base mais nova que é melhor do que backquotes e que todas as crianças legais usam, mas acho que sou uma veterana.) A desvantagem do número 1 é que find encontra muito de arquivos, você pode obter o erro "Linha de comando muito longa".

O número 2 é um recurso especial incorporado em find para fazer uma combinação de comandos find +. Está tudo bem, mas tem duas desvantagens: (1) ele invoca novamente o comando auxiliar ( grep ou qualquer outro) para cada arquivo encontrado, então pode ser lento, e (2) se o comando auxiliar é grep , já que cada chamada de grep vê um nome de arquivo, ele não listará os nomes de arquivo na correspondência, embora você possa contornar isso fazendo -exec grep padrão {} /dev/null \; ou Atualmente, -exec grep -H padrão {} \; .

E depois há o número 3. Até onde eu sei, xargs foi inventado para contornar as limitações dos dois primeiros. Embora o xargs seja, teoricamente, um programa de propósito geral, suspeito que na prática quase nunca seja usado com qualquer par de programas além de find e grep . Trabalha completamente em torno da desvantagem de # 1; ele funcionará com um número arbitrário de arquivos encontrados. É eficiente, mas se você tiver azar, ocasionalmente invocará grep one um último nome de arquivo, o que significa que você ainda desejará usar o truque /dev/null ou -H . E tem uma desvantagem própria: não funciona se algum dos nomes de arquivo encontrados contiver espaços em branco. Mas há uma maneira de contornar isso também:

find dir especificadores de localização -print0 | xargs -0 grep padrão

(Eu desejo que xargs tenha sido escrito para aceitar nomes de arquivos separados por novas linhas em sua entrada por padrão em vez de espaços em branco, mas isso é um discurso para outro dia.)

    
por 28.06.2018 / 12:06