파일을 한 줄씩 병합

파일을 한 줄씩 병합

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

대안은 다음과 같습니다 (ANSI-C 인용을 지원하는 paste셸로 GNU pr테스트됨 ).

pr -mts$'\n' <files>

한 가지 장점은 이 -s옵션이 다중 문자 구분 기호에도 작동한다는 것입니다.


태그가 지정되어 있으므로 명령을 sed사용할 수 있습니다 ( 에서 사용 가능 하지만 다른 구현에 대해서는 확실하지 않음).RGNU 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 sedread 명령을 사용하여 R입력 파일에서 상위 몇 줄을 단계별로 추출하여 병합된 출력을 얻을 수 있습니다.

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

여기서는 2D array@A라고도 알려진 AoA에 파일을 저장합니다. 첫 번째 인덱스는 위치 매개변수 목록의 파일 위치를 나타내고 두 번째 인덱스는 해당 특정 파일에 대한 데이터를 나타냅니다. 끝 블록에서는 }{각 배열에서 하나의 요소를 선택하여 배열을 압축합니다.

관련 정보