Como eu posso extrair uma linha específica em um arquivo de texto, assim como várias linhas contendo uma string específica?

4

Eu tenho uma coleção de arquivos de texto contendo mais dados do que eu preciso. A primeira linha de cada arquivo contém uma string separada por vírgulas que se parece com isso:

stop_id,stop_code,stop_name,stop_desc,stop_lat,stop_lon,location_type,parent_station,zone_id

Então, abaixo dessas chaves, estão todos os dados. Eu preciso extrair um subconjunto desses dados em um novo arquivo de texto para que eu possa trabalhar com o subconjunto (não preciso de todos os dados, é demais).

Estou usando este comando para extrair a primeira linha:

sed -n '1p' source.txt > destination.txt

Também estou usando esse comando para extrair as linhas específicas de que preciso:

grep "string" source.txt > destination.txt

O desafio é que, quando executo os dois comandos no mesmo script (praticamente como estão separados por uma linha ou && ), a saída grep substitui a saída sed . Como posso executar ambos em sequência e ter a saída combinada de ambos?

Eu notei uma pergunta que parece semelhante e envolve o uso de um comando grep mais complexo para localizar a linha única, seguida por um intervalo de linhas. Isso não funcionará aqui porque a primeira linha de cada um dos arquivos dos quais preciso extrair dados é diferente.

Idealmente, quero escrever uma função que possa ser executada em cada um dos arquivos com os quais preciso trabalhar, mas preciso encadear esses comandos e combinar suas saídas primeiro.

    
por Paul Jacobson 29.12.2017 / 09:21

3 respostas

8

Basta alterar a saída grep para acrescentar,

grep "string" source.txt >> destination.txt

    
por 29.12.2017 / 09:24
10

sed pode fazer ambos os trabalhos (imprimir a primeira linha e todas as linhas contendo string ):

sed -n '1p; /string/p' source.txt > destination.txt

ou versão mais longa:

sed -n -e '1p' -e '/string/p' source.txt > destination.txt
    
por 29.12.2017 / 09:26
6

Existem muitas maneiras de fazer isso. Você pode usar um único comando para obter as duas linhas, conforme a @ sed solution da Cyrus . Aqui estão algumas outras ferramentas que podem fazer isso:

awk 'NR==1 || /string/' source.txt > destination.txt
perl -ne 'print if /string/ || $. ==1' source.txt > destination.txt

Você também pode executar os dois comandos que estava executando e simplesmente alterar o segundo para anexar ao arquivo como BANJOSA sugeriu . Alternativamente, você poderia agrupar os dois comandos em um subshel e redirecionar a saída do subshell para um arquivo:

(sed -n '1p' file; grep string file) source.txt > destination.txt

ou

{ sed -n '1p' file; grep string file; } source.txt > destination.txt

Então, se você quiser fazer uma função dessas, seria tão simples quanto adicionar isso ao arquivo de inicialização do seu shell (por exemplo, ~/.bashrc ):

foo(){ sed -n '1p' file; grep string file; } 

E agora você pode executar a função foo para fazer o que quiser:

foo source.txt > destination.txt
    
por 29.12.2017 / 09:48