Imprima várias linhas começando com “D” depois de vários greps

2

Eu tenho dois arquivos de texto. Text-file-1 contém strings (uma string por linha);

C 010
C 020
C 024
.
.
.

Texto-arquivo-2 contém dados no seguinte formato:

C 005 Carbon
D Carbon 1
D Carbon 2
D Carbon 3
D Carbon 4
C 010 Hydrogen
D Hydrogen 1
D Hydrogen 2
C 017 Oxygen
D Oxygen 1
C 020 Nitrogen
D Nitrogen 1
D Nitrogen 2
D Nitrogen 3
C 024 Sulphur
D Sulphur 1
D Sulphur 2
.
.
.

O arquivo de texto-1 contém 30 linhas, mas o arquivo de texto-2 contém dados enormes e no mesmo formato que mencionei. Eu posso grep o texto em Text-file-2 encontrado em Text-file-1 usando o seguinte comando;

awk 'NR==FNR { A[]=1; next }; A[]' Text-file-1 Text-file-2 > filename

Saída para este script

C 010 Hydrogen
C 020 Nitrogen
C 024 Sulphur
.
.
.

Minha saída desejada é

C 010 Hydrogen
D Hydrogen 1
D Hydrogen 2
C 020 Nitrogen
D Nitrogen 1
D Nitrogen 2
D Nitrogen 3
C 024 Sulphur
D Sulphur 1
D Sulphur 2
.
.
.

Agora, eu preciso de uma extensão deste comando, que pode imprimir todas as linhas (começando com "D"), incluindo e depois desta linha. Todas as linhas no arquivo de texto 2 começam com uma letra (C ou D). Esta carta não é útil para mim, mas eu guardei. Por favor, ajude.

    
por Muhammad Sufian 17.09.2013 / 17:41

3 respostas

1

Aqui está outra solução possível, usando sed

while read str; do sed -n "/^$str/,/^C/ {/^$str/p;/^D/p}" Text-file-2; done < Text-file-1

Lembre-se de que a substituição de variáveis do shell por expressões sed deve ser usada com cuidado. Tudo bem, neste caso, porque Text-file-1 contém strings alfanuméricas simples, mas falhará se a variável shell contiver qualquer caractere 'especial' que precise ser salvo na expressão sed.

    
por steeldriver 18.09.2013 / 05:32
2

Veja um script awk que faz o que você quer:

awk '
  NR==FNR { C[]=1; next }
   == "C" { if (C[] == 1) { print; D[]=1 } }
   == "D" { if (D[] == 1) print }
' f1 f2

Exemplo

Veja alguns dados de amostra.

$ cat f1
C 010
C 020
C 024

$ cat f2
C 005 Carbon
D Carbon 1
D Carbon 2
D Carbon 3
D Carbon 4
C 010 Hydrogen
D Hydrogen 1
D Hydrogen 2
C 017 Oxygen
D Oxygen 1
C 020 Nitrogen
D Nitrogen 1
D Nitrogen 2
D Nitrogen 3
C 024 Sulphur
D Sulphur 1
D Sulphur 2

Resultados

$ awk '
>   NR==FNR { C[]=1; next }
>    == "C" { if (C[] == 1) { print; D[]=1 } }
>    == "D" { if (D[] == 1) print }
> ' f1 f2
C 010 Hydrogen
D Hydrogen 1
D Hydrogen 2
C 020 Nitrogen
D Nitrogen 1
D Nitrogen 2
D Nitrogen 3
C 024 Sulphur
D Sulphur 1
D Sulphur 2

Você pode colocar o script awk em seu próprio arquivo, assim, cmd.awk :

NR==FNR { C[]=1; next }
 == "C" { if (C[] == 1) { print; D[]=1 } }
 == "D" { if (D[] == 1) print }

Em seguida, execute da seguinte forma:

$ awk -f cmd.awk f1 f2
C 010 Hydrogen
D Hydrogen 1
D Hydrogen 2
C 020 Nitrogen
D Nitrogen 1
D Nitrogen 2
D Nitrogen 3
C 024 Sulphur
D Sulphur 1
D Sulphur 2
    
por slm 18.09.2013 / 15:54
0

Seus desejos parecem conflitar com o que é atualmente possível.

Se você quiser imprimir o D de ambos os arquivos, use o seguinte: cat file1 file2 | grep -E '^D.+'

O problema é que, se você fizer um gato, você não saberá mais os nomes dos arquivos depois de canalizar, então terá que fazer algo como: grep -El '^D.+' *

    
por user1529891 17.09.2013 / 17:50