encontra um arquivo através de uma pesquisa específica em while loop [closed]

1

Na verdade, ele está relacionado ao meu post anterior organizando diretórios pesquisando uma determinada extensão de arquivo que ainda não foi respondida. Há muitas opções disponíveis para resolver o problema, mas eu estou particularmente interessado em while loop. Em um diretório de trabalho atual, quero pesquisar a existência de um determinado arquivo, examinando determinado conteúdo em um loop while e, em seguida, imprimir apenas o nome da pasta correspondente. O diretório de trabalho atual tem muitas pastas e subpastas. Aqui está o meu script:

while IFS= read -r d; do  
   if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  
done <<  (find . -prune -type d) 

Eu não sei se impor if é uma abordagem correta para fazer dentro do loop ou outra coisa. Por favor guie.

    
por Akand 19.07.2018 / 21:20

3 respostas

2

Por que o grep falha

Fazendo isso em um terminal:

Falha - Aguardando entrada
$ grep "index123"
Works - Recebe entrada de STDIN
$ echo -e "line1\nline2\nindex123blah\n" | grep "index123"
index123blah

O segundo funciona porque apresentamos a entrada para grep para analisar via STDIN. grep receberá informações de STDIN ou de um arquivo. No seu cenário:

if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  

Também não está analisando, por isso está falhando.

Seu problema

Da aparência do seu código, acredito que você queira algo assim. Para começar, aqui estão alguns dados de amostra:

$ mkdir -p 1/2/{3..5}
$ echo "index123" > 1/2/3/blah.out
$ echo "index123" > 1/2/3/blip.out
$ echo "index" > 1/2/blip.out
$ echo "index" > 1/2/blah.out

E uma forma modificada do seu script:

$ cat loopy.bash
#!/bin/bash

while IFS= read -r d; do  
  grep -l "index123" "$d" && exit 1
done < <(find . -type f -name "*.out") 

Em exibição:

$ ./loopy.bash
./1/2/3/blah.out

Emite o primeiro arquivo que encontrou index123 string e sai.

While loop uma boa solução?

Eu não faria assim. Usar um loop while aqui dessa maneira não é necessário. Seria melhor usar uma arquitetura find .... | xargs ... ou find ... -exec do tipo de solução.

Veja @ resposta do DopeGhoti para uma melhor abordagem ao uso de find com -exec ou xargs .

Imprimindo diretório contendo

Se você quiser simplesmente imprimir a árvore de diretórios que contém o arquivo correspondente, use dirname para fazer isso da seguinte forma:

$ cat loopy2.bash
#!/bin/bash

 while IFS= read -r d; do
   grep -q "index123" "$d" && dirname "$d"  && exit 1
 done < <(find . -type f -name "*.out")

e executá-lo:

 $ ./loopy2.bash
./1/2/3
    
por 19.07.2018 / 22:04
1

Este é o seu problema:

if [[ "$d"=="*.out" && grep "index123"]];

Vamos fingir que d=foo.out . Agora, efetivamente, temos:

if [[ grep "index123"]];

Você está tentando dizer a grep para pesquisar a entrada padrão para a expressão /index123/ . Mas não haveria nenhuma entrada chegando a ele, por isso (parece) travar enquanto aguarda a entrada. No entanto, , ele não chegará tão longe, porque if [[ grep "index123" ]] é uma sintaxe inválida. Você preferiria if grep "index123" . Mas novamente - isso simplesmente aguardará a entrada padrão entrar.

Parece que você deseja os retornos de find dos arquivos com o nome *.out , que contêm o texto index123 . Então tente isto:

find . -prune -type d -name \*.out -print0 | xargs -0 grep -l 'index123'

Essa instrução find é bastante complicada, no entanto. Por que find everything e, em seguida, podar os diretórios quando poderíamos procurar apenas os arquivos reais que queremos?

find . -type f -name \*.out -print0 | xargs -0 grep -l 'index123'

Agora você verá todos os arquivos que contiverem o texto que você procura.

Nem precisamos trazer xargs para a tabela, já que find pode invocar grep por conta própria:

find . -type f -name \*.out -exec grep -l 'index123' "{}" \;
    
por 19.07.2018 / 22:00
1

Localizando todos os arquivos *.out que contêm a string index123 no diretório atual:

grep -lF 'index123' ./*.out

Se você quiser fazer um grep recursivo em todos os arquivos *.out , independentemente de onde eles estejam abaixo do diretório atual:

find . -type f -name '*.out' -exec grep -lF 'index123' {} +

Imprimindo o diretório onde a string foi encontrada:

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';'

Saindo depois do primeiro nome do diretório encontrado (usando o GNU find ):

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';' -quit

Dependendo do que você está planejando usar o nome do diretório, você deve substituir o -quit por outro -exec para processar o diretório da maneira que for necessário. vários -exec utilitários em um script de shell chamado de -exec . O que você está não fazendo é canalizar o nome do diretório para outro comando, já que isso geralmente não é seguro, a menos que você tome precauções extras ao delimitar o (s) nome (s) do caminho com caracteres nulos.

Relacionados:

por 19.07.2018 / 22:32