我有 10 个文件,我想将每个文件的第一行、每个文件的第二行等复制到一个大文件中。
文件1.txt是
A
B
C
D
文件2.txt是
E
F
G
H
file3.txt 是
I
J
K
L
我希望有
A
E
I
B
F
J
C
G
K
....
谢谢
答案1
您可以使用paste
它,只需将分隔符设置为换行符即可:
$ paste -d'\n' file1 file2 file3
A
E
I
B
F
J
C
G
K
D
H
L
答案2
这是一个替代方案paste
(已使用GNU pr
支持 ANSI-C 引用的 shell 进行测试)
pr -mts$'\n' <files>
一个优点是该-s
选项也适用于多字符分隔符。
由于sed
已标记,您可以使用R
命令(在 上可用GNU sed
,不确定其他实现)。
sed -e 'R f2' -e 'R f3' f1
答案3
#!/usr/bin/perl
use strict;
# how many files to open? 10 in the question, 3 in examples.
my $numfh=3;
# a counter for the number of open file handles
my $openfh=$numfh;
# open an array of filehandles, one for each input file.
my @fh = ();
for my $i (1..$numfh) {
open($fh[$i],"<","file$i.txt") || die "Couldn't open file$i.txt for read: $!";
};
# open the output file.
open (my $out,">","bigfile.txt") || die "Couldn't open bigfile.txt for write: $!";
# repeat until there are no more open file handles.
until ($openfh < 1) {
for my $i (1..$numfh) {
if (eof($fh[$i])) {
# if an input file is eof, close it and decrement openfh counter.
$openfh--;
close($fh[$i]);
} else {
# print a line of input from the current input file to the output file.
print $out scalar readline $fh[$i]
};
};
}
将其另存为,例如,merge.pl
并使其可执行chmod +x merge.pl
。然后像这样运行它:
$ ./merge.pl
输出:
$ cat bigfile.txt
A
E
I
B
F
J
C
G
K
D
H
L
这是使用 @ARGV 并打印到 @terdon 的 STDOUT 的版本:
#!/usr/bin/perl
use strict;
my @fh = ();
my $i=1;
for my $f (@ARGV) {
open($fh[$i++], "<", $f) || die "Couldn't open $f for read: $!";
};
my $numfh=$#fh; my $openfh=$numfh;
until ($openfh < 1) {
for my $i (1..$numfh) {
if (eof($fh[$i])) {
$openfh--;
close($fh[$i]);
} else {
print scalar readline $fh[$i]
};
};
}
或者使用散列来保存文件句柄而不是数组:
#!/usr/bin/perl
use strict;
my %fh = ();
for (@ARGV) {
open($fh{$_}, "<", $_) || die "Couldn't open $_ for read: $!";
};
while (keys %fh) {
for my $f (@ARGV) {
next unless (defined($fh{$f}));
if (eof($fh{$f})) {
close($fh{$f});
delete($fh{$f});
} else {
print scalar readline $fh{$f}
};
};
}
运行如下:
$ ./merge.pl file[123].txt > bigfile.txt
输出与硬编码版本相同。
答案4
使用GNU sed我们可以使用R
read 命令逐步从输入文件中提取最上面几行,以获得合并的输出。
sed -e "
$(printf 'R%s\n' file{2..9}.txt file10.txt)
" file1.txt
perl -lne '
push @{$A[@ARGV]}, $_}{
for my $i (0..$#{$A[0]}){
print for map { $A[$_][$i] } reverse 0..$#A
}
' file{1..9}.txt file10.txt
在这里,我们将文件存储在 AoA 中,也称为 2D 数组 @A。第一个索引指的是位置参数列表中的文件位置,第二个索引指的是该特定文件的数据。在结束块中,}{
我们通过从每个数组中选取一个元素来压缩数组。