Como intercalar as linhas de dois ou mais arquivos?


10

Eu tentei obter os 2 arquivos de saída em um único arquivo. Eu tentei abaixo do comando:

cat file1 file2

mas aqui os file2dados estão anexados file1.

O que eu preciso é da file11ª linha seguida pela file2primeira linha e da file1segunda linha seguida pela file2segunda linha etc.

Alguém pode me dizer como fazer isso de uma maneira simples?

Respostas:


17

Há um aplicativo para isso!

$ cat file1
file1 line1
file1 line2

$ cat file2
file2 line1
file2 line2

Agora, se você passar esses arquivos como argumentos para paste:

$ paste -d' ' file1 file2
file1 line1 file2 line1
file1 line2 file2 line2

Se por "arquivo1 1ª linha seguido por arquivo2 primeira linha e arquivo1 segunda linha seguido por arquivo2 segunda linha etc.", você quer dizer que deseja uma nova linha entre cada linha colada, basta ajustar a -dopção (delimitador).

$ paste -d'\n' file1 file2
file1 line1
file2 line1
file1 line2
file2 line2

2

POSIX Awk; isso funciona com uma quantidade arbitrária de arquivos e os arquivos nem precisam ter a mesma quantidade de linhas. O script continua até que todos os arquivos estejam fora de linha:

BEGIN {
  do {
    br = ch = 0
    while (++ch < ARGC)
      if (getline < ARGV[ch]) {
        printf ch < ARGC - 1 ? $0 FS : $0 RS
        br = 1
      }
  } while (br)
}

Há um problema com isso, se a entrada contiver caracteres '%', ela tentou avaliá-los dentro do printf. Minha atualização seria (não tenho certeza se isso está perfeitamente correto):printf "%s", ((ch < ARGC - 1) ? $0 FS : $0 RS)
Scala William

0

Solução bash rápida

# Takes as many file arguments as needed
function InterleaveFiles {

    local counter=0
    local hasLine=true

    while [ $hasLine == true ]; do
            hasLine=false
            for i in "$@"; do
                    line=$(awk 'NR == num_line {print; exit}' num_line=$((counter+1)) "$i")
                    if [ -n "$line" ]; then
                            echo "$line"
                    hasLine=true
                    fi
            done
            counter=$((counter+1))
    done
}

InterleaveFiles arquivo1 arquivo2 arquivo3 arquivo4


-2
paste -d '\n' file1 file2 > file3

onde file1e file2estão os arquivos de entrada e file3será a saída criada.


1
Bem-vindo ao U&L Stack Exchange! Essa resposta é quase idêntica à resposta de Terdon . Nos casos em que você acha que pode melhorar uma resposta, mas não fornece informações substancialmente novas, considere propor uma edição a uma resposta existente . As respostas também são reordenadas com base na votação; portanto, cada resposta deve ser independente ou se referir a outra resposta. É por isso que os oneliners de shell devem ser acompanhados de uma descrição que explique sua operação.
Thomas Nyman
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.