Mesclar arquivos usando o método zipper / late merge

6

Estou procurando um método interessante de mesclar dois ou mais arquivos linha por linha usando o método zipper (também chamado de late merge). Assumindo que temos três arquivos, o resultado deve ficar assim:

line1 file1
line1 file2
line1 file3
line2 file1
line2 file2
line2 file3
...

EDITAR

Eu escrevi um pequeno script python capaz de fazer isso:

#!/usr/bin/python

import sys, itertools

fileList = []
for file in sys.argv[1:]:
    f = open(file, "r")
    fileList.append(f.read().split("\n"))

for z in itertools.izip_longest(*fileList):
    print "\n".join([i for i in z if i is not None])

Ainda me pergunto se existe alguma ferramenta padrão ou uma combinação inteligente deles fazendo a mesma coisa.

    
por scai 11.08.2012 / 17:44

3 respostas

5

Normalmente, uso paste de coreutils para esse tipo de coisa:

paste -d'\n' file1 file2 file3
    
por 12.08.2012 / 13:55
2

eu escrevi um pequeno script perl, que faz isso

#!/usr/bin/perl

do { open($fh[$_], "<$ARGV[$_]") or die("'$ARGV[$_]' does not exist") } for(0..$#ARGV);


for($i=0;;$i++) {
    $j=$#ARGV+1;

    $fh = $fh[$i%$j];
    if ( $_ = <$fh> ) {
        print $_;
    } else {
        $end |= 2**($i%$j);
    }

    if($end == (2**($j))-1) {
        last;
    }
}

close($_) for(@fh);

salve em um arquivo uma chamada como

script.pl file1 file2 file3 ... > merge

Essa é pelo menos uma possibilidade para resolver sua tarefa.

    
por 11.08.2012 / 19:53
2

Outra versão do Python que não precisa ler todos os arquivos na memória de uma só vez:

paddy$ more f[123].tmp
::::::::::::::
f1.tmp
::::::::::::::
line1 file1
line2 file1
line3 file1
::::::::::::::
f2.tmp
::::::::::::::
line1 file2
line2 file2
line3 file2
line4 file2
::::::::::::::
f3.tmp
::::::::::::::
line1 file3
line2 file3
line3 file3
line4 file3
line5 file3
paddy$ python2.7 -c 'import sys, itertools
files = [open(fname) for fname in sys.argv[1:]]
sys.stdout.write("".join("".join(lines) for lines in itertools.izip_longest(*files, fillvalue="") ))' f[123].tmp
line1 file1
line1 file2
line1 file3
line2 file1
line2 file2
line2 file3
line3 file1
line3 file2
line3 file3
line4 file2
line4 file3
line5 file3
paddy@paddy-ThinkPad-T61:~$ 

Substitua izip_longest por zip_longest e ele também funcionará no Python 3.x.

    
por 28.08.2012 / 23:35