Como extrair linhas de um arquivo de texto que contenha strings de uma lista em outro arquivo? [duplicado]

4

Eu tenho um arquivo contendo informações sobre a população de várias cidades. Eu tenho outro arquivo que é uma lista dos nomes de um subconjunto dessas cidades. Eu quero selecionar as informações da população do primeiro arquivo usando o segundo arquivo. Como eu faria isso?

Exemplos:

Arquivo 1: ma-towns.txt

Acton   Town    Middlesex   Open town meeting   21,924  1735  
Acushnet    Town    Bristol Open town meeting   10,303  1860  
Adams   Town    Berkshire   Representative town meeting 8,485   1778  
Agawam  City[4] Hampden Mayor-council   28,438  1855  
Alford  Town    Berkshire   Open town meeting   494 1773  
Amesbury    City    Essex   Mayor-council   16,283  1668  
Amherst Town    Hampshire   Representative town meeting 37,819  1775  

Arquivo 2: town-list.txt

Acton  
Adams  
Agawam 

A saída desejada seria

Acton   Town    Middlesex   Open town meeting   21,924  1735  
Adams   Town    Berkshire   Representative town meeting 8,485   1778  
Agawam  City[4] Hampden Mayor-council   28,438  1855   

Basicamente, como dito geralmente, extraia a linha se ela contiver a string em uma das linhas do arquivo 2.

    
por abnry 26.07.2016 / 16:17

2 respostas

7
grep -f <(sed 's/.*/\^&\>/' town-list.txt) ma-towns.txt

Explicação:

grep -f filefile para uma lista de padrões para correspondência. Estamos pesquisando na lista ma-towns.txt , usando padrões de town-list.txt . Cada linha separada é tratada como um novo padrão, ou seja, um novo termo de pesquisa.

No entanto, isso não é o suficiente, então incluímos um sed para formatar os termos de pesquisa assim:

^Acton\>
^Adams\>
^Agawam\>

O ^ faz o grep corresponder apenas a esse padrão no início de uma linha, e o \> faz o grep corresponder apenas se a palavra terminar nesse ponto.

Juntos, isso garante que o termo de pesquisa apenas analise o início da linha (onde estão os nomes das cidades) e que o termo de pesquisa termine onde o nome da cidade termina.

O comando sed executa o comando s (substitute), na forma s/search/replace/ .

O termo de pesquisa .* corresponde a uma linha inteira. A substituição, \^&\> , substitui-a por um caracter literal ^ , seguida pela linha original, seguida pelo texto \> .

O que esta resposta faz que a outra não:

  • Manipula nomes de cidades começando com um traço ou contendo barras invertidas (o que é improvável, mas se a entrada for tirada de um usuário, você não deseja que eles sejam capazes de quebrar seus scripts de maneiras imprevisíveis). Note que ambas as respostas tratam nomes de cidades como um regex em vez de um termo de pesquisa literal.
  • Mostra as cidades na ordem original, conforme especificado em ma-towns.txt
  • Executa melhor
  • Pesquisa o início da linha para o nome da cidade, não apenas em qualquer lugar na linha
  • Não corresponde a uma cidade se apenas uma correspondência de substring (por exemplo, Waterloo não corresponder a Waterlooville )
por 26.07.2016 / 16:40
5

Isso lerá as linhas de file2 e parse file1 com grep usando as linhas:

while read line; do
  grep "${line}" file1
done < file2
    
por 26.07.2016 / 16:30

Tags