Tenho cerca de 500 strings e quero procurar os arquivos que as contêm dentro de um diretório e obter os nomes dos arquivos que contêm as strings. Até agora tenho usado:
find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print
mas o problema é que uma string pode ser encontrada em muitos arquivos, por isso é difícil encontrar quais strings estão presentes e quais estão faltando devido à enorme produção. Você pode me ajudar a imprimir as strings com os nomes dos arquivos correspondentes onde foram encontradas.
Responder1
Você deveria apenas grep
fornecer os nomes dos arquivos. GNU grep
pode fazer isso:
grep -HFf ../strings.txt *
Isso apresentará uma saída semelhante a:
[filename]:[matched_line]
...para cada correspondência em cada arquivo no diretório. Você também pode obter números de linha:
grep -HnFf ../strings.txt *
...que fornece...
[filename]:[line_number]:[matched_line]
Responder2
O problema é que você está passando um arquivo por vez para o grep
. Quando grep
vê um único arquivo em sua linha de comando, ele assume que você sabe exatamente onde está pesquisando, portanto não exibe o nome do arquivo na frente das correspondências.
Um truque para forçar grep
a saída sempre de um nome de arquivo é passar também /dev/null
(onde nunca haverá correspondência). Algumas implementações do grep têm uma opção para isso: -H
.
Além disso, você pode usar -exec … {} +
em vez de -exec … {} \;
executar o programa para vários arquivos de uma só vez. Isso é mais rápido. Você ainda deve passar /dev/null
ou -H
, porque pode acontecer que o comando seja invocado em exatamente um arquivo, seja porque há um único arquivo correspondente ou porque há muitas correspondências exigindo que grep
seja invocado várias vezes e uma vez diga respeito a um único arquivo.
find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +
GNU grep e implementações recentes do BSD (incluindo OSX) suportam opções para chamar grep
recursivamente sem exigir find
.
grep -R --include='LYFNRE.*' -f file1.txt -H .
Alternativamente, você pode fazer globbing recursivo em seu shell. No zsh, isso funciona imediatamente. No bash, você precisa executar shopt -s globstar
primeiro e tomar cuidado, pois o bash recorre por meio de links simbólicos para diretórios (ao contrário de find
ou zsh).
grep -f file1.txt /dev/null **/LYFNRE.*
Responder3
use egrep:
egrep -n "str1|str2|str3" file_names
-n imprimirá o número da linha no arquivo específico em que a string foi encontrada