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

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:




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

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

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.