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.