ジッパー方式(マージ後とも呼ばれる)を使用して、2つ以上のファイルを1行ずつマージする良い方法を探しています。 3つのファイルがあると仮定すると、結果は次のようになります。
line1 file1
line1 file2
line1 file3
line2 file1
line2 file2
line2 file3
...
編集する
私はこれを行う小さなPythonスクリプトを書いています。
#!/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])
同じことを行うことができる標準的なツールや、これらの巧妙な組み合わせがあるかどうかを知りたいです。
答え1
私は通常この種の仕事にpaste
fromを使用します。coreutils
paste -d'\n' file1 file2 file3
答え2
すべてのファイルを一度にメモリに読み込む必要がない別のPythonバージョン:
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:~$
izip_longestをzip_longestに置き換えると、Python 3.xでも動作します。
答え3
私はこれを行うPerlスクリプトを書いた。
#!/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);
ファイルに保存し、次のように呼び出します。
script.pl file1 file2 file3 ... > merge
これはあなたの仕事を解決するための少なくとも1つの可能性です。