localizando todas as palavras em um arquivo de texto que aparece em outro arquivo de texto

4

Suponha que eu tenha dois arquivos a.txt e b.txt . Quero encontrar todas as palavras em a.txt que aparecem em b.txt .

Existe um comando específico para fazer isso?

    
por Reyx_0 12.12.2015 / 21:43

4 respostas

7

Com bash , zsh e algumas implementações de ksh :

comm -12 <(tr -s '[:space:]' '[\n*]' < a.txt | sort -u) \
         <(tr -s '[:space:]' '[\n*]' < b.txt | sort -u)

Lá, word é uma sequência de caracteres sem espaçamento (cuidado com o GNU tr , que não funciona com caracteres de espaçamento de bytes múltiplos).

comm localiza as linhas comuns entre dois arquivos classificados. Sem opções, imprime 3 colunas: as linhas somente no arquivo1, as linhas somente no arquivo2 e as linhas comuns a ambos. Você adiciona -1 , -2 , -3 para remover as colunas correspondentes da saída. Portanto, comm -12 apenas deixa a terceira coluna (as linhas comuns).

tr -s '[:space:]' '[\n*]' tr analisa qualquer equação s de caracteres da classe space em novas linhas, para colocar cada palavra em sua própria linha .

sort -u classifica e remove as duplicatas da saída de tr .

A substituição de processo <(...) canaliza as saídas dos comandos tr|sort para comm .

com zsh :

w1=($(<a.txt)) w2=($(<b.txt))
print -rl -- ${(u)${w1:*w2}}

Lá, palavra é uma sequência de caracteres diferente de espaço, tabulação, nul e nova linha (com o valor padrão de $IFS ).

$(<a.txt) é uma versão otimizada de $(cat a.txt) , em que zsh lê o conteúdo do arquivo sozinho sem invocar cat , pois ele não é citado, ele passa por uma divisão de palavras (mas não globbing contrário a outros shells) .

Portanto, w1 e w2 são matrizes contendo todas as palavras em a.txt e b.txt .

${w1:*w2} é um operador zsh que fornece a interseção de duas matrizes (os elementos comuns a ambos). (u) é um sinalizador de expansão de parâmetro que retém elementos exclusivos (remove duplicados).

print -rl imprime cada argumento um por linha.

    
por 12.12.2015 / 23:32
2
# Create dummy text file containing two words
$ echo -e "overflow\ngrep" > b
# Search in file for lines containing one word from file b
$ grep --color --fixed-strings --file b /usr/share/dict/words

Resultado no meu sistema:

overflow
overflow's
overflowed
overflowing
overflows

Adicione o parâmetro - somente correspondência (-o) para obter apenas as palavras e não a linha completa em que elas aparecem.

    
por 12.12.2015 / 23:04
-1

Supondo que as palavras nos arquivos são separadas por LF e as palavras consistem apenas em caracteres "legais" e não há nenhuma última LF em b.txt, então

egrep 'tr '\n' '|' < b.txt' a.txt

pode fazer o truque.

    
por 12.12.2015 / 22:15
-1

Apesar de não funcionar em nível de palavra, mais para trabalhar em linhas, isso pode ser útil para você ou para alguém que esteja procurando uma resposta.

diff --left-column --from-file=a.txt --to-file=b.txt

Compara do arquivo a.txt para o arquivo b.txt, exibindo apenas linhas comuns.

    
por 12.12.2015 / 22:25