Use uma lista de palavras para grep em outra lista

8

Eu tenho uma lista com 250 linhas. Eu tenho que executar todos eles através de um servidor web para obter uma lista de saída. Esta lista, no entanto, retorna muito mais linhas do que estou interessado. Diga, meu list.txté:

a.1
b.1
etc

então a saída é output.txt:

a.1 a b c
a.2 b a b
a.3 d k o
b.1 b o p
b.2 o i y
b.3 p i y
etc

É possível usar o comando grep para procurar todas as palavras em list.txt no output.txt e gerar a lista "desejado"? Preciso de toda a linha no meu output.txt. Sou novo em scripts, mas o que eu gostaria é de algo como

grep list.txt output.txt > wanted.txt

Não consegui encontrar nenhum exemplo disso

Ditte
fonte
Os dois estão em ordem alfabética, como nos seus exemplos?
Oli
Não, tenho uma ordem não alfabética específica em meu list.txt, mas o output.txt é alfabético, mas gostaria que ele contivesse apenas os "hits" do meu list.txt na mesma ordem não alfabética
Ditte

Respostas:

11

Eu ignoraria greppor este. É bom para expressões regulares, mas não parece que você realmente precise disso aqui. commpode comparar dois arquivos e mostrar interseções. Usando seus exemplos exatos:

$ comm -12 list.txt output.txt 
a.1
b.1
etc

Isso é mais rápido do que qualquer grep, mas depende muito dos arquivos que estão sendo classificados. Se não estiverem, você pode pré-classificá-las, mas isso alterará a saída para que também seja classificada.

comm -12 <(sort list.txt) <(sort output.txt) 

Como alternativa, esta resposta do iiSeymour permitirá que você faça isso grep. Os sinalizadores solicitam um arquivo de entrada e forçam uma pesquisa por palavra-chave de cadeia fixa. Isso não depende do pedido, mas será baseado no output.txtpedido. Inverta os arquivos, se desejar, na ordem do list.txt.

$ grep -wFf list.txt output.txt 
a.1
b.1
etc

Se você list.txté realmente grande, talvez seja necessário abordar isso um pouco mais de forma iterativa e passar cada linha para grep separadamente. Isso aumentará enormemente o tempo de processamento. No exemplo acima, você estaria lendo output.txtuma vez, mas desta forma você leria e processaria para cada linha list.txt. É horrível ... Mas pode ser sua única escolha. No lado positivo, ele classifica as coisas pela list.txtordem.

$ while read line; do grep -wF "$line" output.txt; done < list.txt
a.1
b.1
etc
Oli
fonte
1
Isso é realmente inteligente! Qual é o motivo do -12?
Ditte
3
-1suprime linhas exclusivas para o primeiro arquivo, -2suprime linhas exclusivas para o segundo arquivo e -3suprime linhas comuns para ambos. Para obter apenas as linhas comuns, suprimimos os únicos -12.
Oli
agradável! Eu acho que vou usar o comando comm. E então, quando eu quiser classificar o output.txt para ter a mesma ordem que list.txt, usarei o comm -12 <(class list.txt) <(class output.txt) depois?
Ditte
O comando comm não me deu a linha inteira no result.txt (e eu preciso de tudo para obter as informações a partir daí). Mas se eu tentar o comando grep, ele receberá o grep: sem memória. Isso significa que é muito grande?
Ditte
o segundo exemplo tem um redirecionamento STDIN redundante que o shell sinalizaria como um erro. crie arquivos temporários ou use um fd extra com uma classificação em segundo plano canalizada para ele (complicada na maioria dos shells) ... essa é mais uma pergunta de programação mais solicitada no Stack Overflow . pessoalmente, eu estaria fazendo isso em python.
11139 Skaperen