逐行合并文件

逐行合并文件

我有 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我们可以使用Rread 命令逐步从输入文件中提取最上面几行,以获得合并的输出。

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。第一个索引指的是位置参数列表中的文件位置,第二个索引指的是该特定文件的数据。在结束块中,}{我们通过从每个数组中选取一个元素来压缩数组。

相关内容