Encontre arquivos que contenham um conjunto de palavras

1

Estou usando o grep para encontrar arquivos dentro de um diretório, contendo um conjunto de palavras. Mas as linhas de busca grep contendo essas palavras, o que eu quero é que o grep me mostre os arquivos ou arquivos contendo todas essas palavras, mesmo em linhas diferentes.

grep -lw "ből\|dének\|jeként\|jében\|jéből\|jéhez\|jének\|jéről\|jét\|jével\|jéül" *model.txt

Mas não é válido se o arquivo contiver uma ou duas palavras. Deve conter todo o conjunto de palavras

Como posso conseguir isso com o bash?

Estou usando o código sugerido pelo Tagwint

find -name '*model.txt' | while read f; do [[ "$(grep -o -w -f patterns  $f| sort -u|wc -l)" -eq "$(cat patterns | wc -l)" ]] && echo $f; done

Como poderia ser modificado para mostrar também o número de ocorrências encontradas em cada arquivo? Como ..

685 01_táska.model.txt
687 02_dinnye.model.txt
685 03_kapu.model.txt
685 04a_nő.model.txt
685 04b_büdzsé.model.txt
    
por Firefly 21.03.2016 / 14:40

2 respostas

2

Eu acho que por 'solução mais curta' você quer dizer linha mais curta, você não pode encurtar sua lista muito longa, certo?

Sugiro que você coloque todas as palavras em um arquivo e faça uso da opção -f grep. Então a solução abaixo faz uso da opção -o que fornece as únicas partes correspondentes. Isso resulta na lista de todas as palavras correspondentes em um arquivo. Ordenar, em seguida, uniqing que lista se corresponde a lista de padrões significa exatamente que o arquivo tem todos eles. wc -l conta linhas.

find -name '*model.txt' | while read f; do [[ "$(grep -o -w -f patterns  $f| sort -u|wc -l)" -eq "$(cat patterns | wc -l)" ]] && echo $f; done

padrões é o nome do arquivo que contém suas palavras de pesquisa:

#cat patterns
ből
ből
dének
jeként
jé
....

Note também a opção -w do grep, que garante correspondência apenas com palavras inteiras. Caso contrário, o cálculo pode dar errado para substirng palavras como alegria e alegria ful

É claro que você pode ter um visual mais agradável do onliner, se isso for importante para você

Atualizar Certifique-se de que o arquivo padrão não tenha linhas vazias.

Atualização2Certifique-sedequeoseuarquivodepadrõesnãotemduplicatas-issoestragaráafesta

Atualização3

Paraterumcontadordeocorrênciasnafrentedonomedoarquivo:

find-name'*model.txt'|whilereadf;do[["$(grep -o -w -f patterns  $f| tee /tmp/$f |sort -u|wc -l)" -eq "$(cat patterns | wc -l)" ]] && echo $(cat /tmp/$f|wc -l) $f ; rm /tmp/$f; done

A idéia é salvar todas as correspondências em tempo real em um arquivo temporário e contá-las antes de classificá-las / uni-las. Limpe o arquivo tmp apenas para manter boas maneiras.

    
por 21.03.2016 / 17:30
1

Aqui está um script awk que memoriza quais palavras ele viu e imprime os nomes dos arquivos que contém todas as palavras necessárias.

awk -v required_words='ből dének jeként jében jéből jéhez jének jéről jét jével jéül' '
    function check() {
        for (w in seen) if (!seen[w]) return;
        print last_file;
    }
    BEGIN {
        split(required_words, a);
        for (i in a) seen[a[i]] = 0;
    }
    NR==1 { last_file = FILENAME; }
    FNR==1 && NR!=1 { check(); for (w in seen) seen[w] = 0; }
    END { check() }
    { split($0, a, /[^[:alpha:]]+/);
      for (i in a) if (a[i] in seen) seen[a[i]]=1; }
' *model.txt
    
por 22.03.2016 / 02:06