Eu quero adicionar “n” linhas de um arquivo (digamos, arquivo1) em outro arquivo abaixo das “n” ocorrências de uma string em outro arquivo, a fim

0

Exemplo

Arquivo 1:

This Dog
This Cat
This Duck
This Horse

Arquivo 2:

...
Animal Name
...

AniMal Type
...

AnIMal Class
...

animal Brand
...

Eu quero fazer o seguinte:

  • adicione a Linha 1 do Arquivo 1 (Este Cachorro) logo abaixo da primeira ocorrência de "Animal" (Ignorar caso)
  • adicione a linha 2 do Arquivo 1 (Este Gato) logo abaixo da segunda ocorrência de "Animal" (Ignorar caso)
  • adicione a linha 3 do Arquivo 1 (Este Pato) logo abaixo da terceira ocorrência de "Animal" (Ignorar caso)
  • adicione a linha 4 do Arquivo 1 (este cavalo) logo abaixo da quarta ocorrência de "Animal" (ignorar o caso)
  • ...

Portanto, em geral, a linha n do Arquivo 1 deve ser adicionada logo abaixo da enésima ocorrência de "Animal" (Ignorar maiúsculas e minúsculas).

Então, como eu faço isso usando "sed" ou "awk" ou qualquer comando no Linux?

    
por Prasath Iyer Krishnamoorthy 03.04.2017 / 04:16

3 respostas

3

Com o GNU sed:

$ sed '/^animal/IR File1' File2
...
Animal Name
This Dog
...

AniMal Type
This Cat
...

AnIMal Class
This Duck
...

animal Brand
This Horse
...

onde as extensões GNU são as seguintes:

The I modifier to regular-expression matching is a GNU extension which causes the regexp to be matched in a case-insensitive manner.

e

R filename

Queue a line of filename to be read and inserted into the output stream at the end of the current cycle, or when the next input line is read. Note that if filename cannot be read, or if its end is reached, no line is appended, without any error indication.

    
por 03.04.2017 / 04:36
1

Esta solução awk deve funcionar:

awk 'NR==FNR{a[NR]=$0;next};1;tolower($1)=="animal"{print a[++i]}' file1 file2 > file3

NR == FNR {a [NR] = $ 0; next} acumula dados file1 em uma matriz, pulando para a próxima linha de entrada para evitar o processamento do arquivo2 nesse estágio.

1 imprime cada linha de entrada do arquivo2.

tolower ($ 1) == "animal" {imprimir a [++ i]} combina "animal" sem distinção entre maiúsculas e minúsculas, e gera o item da matriz correspondente, pré-incrementando o índice da matriz.

    
por 03.04.2017 / 04:30
0

Sed

Basta anexar um . após a última linha de file_1 para sinalizar o final de file_1 para sed , pois sed não tem noção de FNR de awk , IOW, sed the POSIX variety não tem como saber quando um arquivo termina e o próximo começa.

A idéia essencial é armazenar os nomes dos animais no hold area e, quando chegar a hora de ler no file_2 , pegamos cada parte separada por nova linha do hold & Anexe-o ao pattern space e, ao mesmo tempo, detach do hold . Este exercício attach<->detach é feito apenas na linha que compreende a string literal animal em uma forma que não diferencia maiúsculas e minúsculas.

sed -e '
   1{
      :file1
         N
      /\n\.$/!bfile1
      s///;h;d
   }

   /^[aA][nN][iI][mM][aA][lL]/!b

   G
   s/\n/&&/2;ta
   b

  :a
   h;s/.*\n\n//;x
   s/\n\n.*//

' file_1 file_2
    
por 03.04.2017 / 04:36