Mesclar linhas alternativas de dois arquivos

9

Arquivo1:

.tid.setnr := 1123 
.tid.setnr := 3345 
.tid.setnr := 5431
.tid.setnr := 89323

Arquivo2:

.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60

Arquivo de saída:

.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
pmaipmui
fonte
2
Por favor sempre mencionar o seu sistema operacional. Muitas ferramentas padrão se comportam de maneira diferente nos diferentes sistemas operacionais, portanto, precisamos saber o que você está usando.
terdon

Respostas:

23

Usando paste:

paste -d \\n file2 file1
Stephen Kitt
fonte
5

Outra solução awk:

awk '{print; getline < "file1"; print}' file2
Glenn Jackman
fonte
5

A pastesolução é a mais portátil e mais eficiente. Estou apenas mencionando essa alternativa, caso você prefira seu comportamento no caso em que os dois arquivos não tenham o mesmo número de linhas:

Com o GNU sed:

sed Rfile1 file2

Se file1tiver menos linhas do que file2, quando file1estiver esgotado, sednão produzirá nada para ele (ao contrário de linhas vazias para paste).

Se file1tiver mais linhas do que file2, essas linhas extras serão descartadas (em vez de imprimir linhas vazias para file2com paste).

$ paste a b
1       a
2       b
3
4
$ paste -d \\n a b
1
a
2
b
3

4

$ sed Rb a
1
a
2
b
3
4
$ sed Ra b
a
1
b
2
Stéphane Chazelas
fonte
4

Usando awk( gawk, nawk, mawk):

awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1 > outputfile
  • NR==FNR {x[FNR]=$0;next}: NR==FNRé correspondido apenas se o número do registro atual for igual ao número do registro atual do arquivo (portanto, é correspondido apenas durante o processamento do primeiro arquivo): armazena o registro atualmente processado na matriz xem um índice igual ao número do registro atual e ignora o Registro atual
  • {print x[FNR]"\n"$0}: imprime o conteúdo da matriz xem um índice igual ao número do registro de arquivo atual seguido por uma nova linha e pelo conteúdo do registro atual
~/tmp$ cat file1
.tid.setnr := 1123
.tid.setnr := 3345
.tid.setnr := 5431
.tid.setnr := 89323
~/tmp$ cat file2
.tid.info := 12
.tid.info := 3
.tid.info := 44
.tid.info := 60
~/tmp$ awk 'NR==FNR {x[FNR]=$0;next} {print x[FNR]"\n"$0}' file2 file1
.tid.info := 12
.tid.setnr := 1123
.tid.info := 3
.tid.setnr := 3345
.tid.info := 44
.tid.setnr := 5431
.tid.info := 60
.tid.setnr := 89323
kos
fonte
Está dando o resultado, mas não exatamente o mesmo que eu queria. As linhas tid.info estão surgindo após as linhas tid.setnr no meu arquivo de saída.
Pmaipmui
@Nainita Isso é o que você está mostrando no seu exemplo de saída.
kos
@Nainita De qualquer forma, para mudar a ordem da saída, basta alternar file1e file2no comando.
kos
Sim ... fiz o mesmo, mas estava imprimindo exatamente como antes. após a impressão de tid.setnr, foi considerado tid.info.
Pmaipmui
1
@mikeserv No entanto, desde que eu estive lá, tentei mawktambém, e funciona também. Enfim sendo razoável eu não posso ver por que ele não deveria trabalhar apenas o contrário (ou seja, apenas mudando arquivos). Não é que se awkpreocupe com a entrada, linhas são linhas. Se algo não fosse suportado por sua versão, ele teria quebrado da primeira vez. Muito mais facilmente, simplesmente OP cometeu um erro ao alternar os arquivos de entrada nos argumentos.
kos
-1

A solução mais fácil é dada abaixo.

cat file1 >> file2

ou

cat file2 >> file1
sachin
fonte
1
sachin, leia a pergunta novamente; isso anexa o conteúdo de um arquivo ao conteúdo de outro arquivo. Não mesclar os arquivos alternando as linhas (para uma linha de file1seguida, uma linha de file2e assim por diante ...)
don_crissti