각 행 쌍의 정보를 하나의 행으로 결합하려면 어떻게 해야 합니까?

각 행 쌍의 정보를 하나의 행으로 결합하려면 어떻게 해야 합니까?

다음과 같은 데이터가 있습니다(실제 데이터에는 50,000자릿수와 8000행이 넘습니다).

입력하다:

1 11122
1 21121
2 22221
2 11122
3 21121
3 11122

동일한 이름을 가진 첫 번째 행의 값 옆에 두 번째 행의 값을 배치하고 싶습니다. 또한 각 값 쌍 사이의 구분 기호로 두 개의 공백이 있어야 하고, 서로 다른 값 쌍 사이의 구분 기호로 탭이 있어야 합니다. 출력은 다음과 같아야 합니다.

산출:

1   1  2    1  1    1  1    2  2    2  1
2   2  1    2  1    2  1    2  2    1  2
3   2  1    1  1    1  1    2  2    1  2

어떤 제안이 있으십니까?

답변1

나는 Perl을 사용하고 다음과 같이 oneliner로 실행합니다.

perl -wne 'sub parseline { ($id,$v) = split; return split //,$v };
    @a = parseline();
    print "$id\t";
    $_ = <>;
    @b = parseline();
    for ($i=0; $i<@a; $i++) {
      print "$a[$i]  $b[$i]\t"
    };
    print "\n"' < input  > output

설명하다:

  • perl -wne각 입력 줄에 대해 나머지 명령을 실행합니다.
  • sub parseline { .... }입력을 구문 분석하고 줄의 첫 번째 숫자를 설정 $id하고 나머지는 문자 배열로 반환합니다.
  • @a=parseline()문자의 첫 번째 행은 @a 배열에 저장됩니다.
  • 다음으로 인쇄 $id하고 TAB( \t) 을 누릅니다.
  • $_=<>; @b=parseline();다음 (짝수) 행을 읽고 해당 데이터를 배열에 넣습니다.@b
  • for ($i=0; $i<@a; $i++) { print "$a[$i] $b[$i]\t" }배열의 각 요소에 대해 @a요소, 두 개의 공백, 배열의 해당 요소를 인쇄한 @b다음 탭을 인쇄합니다.
  • print "\n"끝에 개행 문자를 인쇄합니다
  • at start 매개변수로 인해 -n전체 프로세스는 3행, 5행, 7행 순으로 시작됩니다.perl
  • < input > output입력을 읽는 파일과 출력을 쓰는 파일을 나타냅니다.

참고: 코드는 각 줄 끝에 추가 탭을 인쇄합니다. 크라우드소싱을 방지하고 코드를 좀 더 단순하게 유지하기 위한 독자의 연습으로 이를 제거했습니다. 또한 코드에서는 쌍을 이루는 행이 항상 두 개의 행이 차례로 연속되는 것으로 가정합니다(예제 참조).

입력 파일을 한 줄씩 처리하므로 수천 줄에 걸쳐 쉽게 선형적으로 확장할 수 있습니다.

답변2

pairwise이는 모듈 의 함수를 사용하여 List:MoreUtils두 배열을 연결하고 ID가 일치하는 행(첫 번째 필드)이 연속 행에 있을 필요가 없는 Matija Nalis의 스크립트 버전입니다 . 즉, 여러 줄로 구분할 수 있습니다.

#! /usr/bin/perl

use strict;
use warnings;
use List::MoreUtils qw(pairwise);

sub parseline { my ($id,$v) = split; return $id, split //,$v };

my %ID=();

while (<>) {
    my ($id, @line) = parseline();

    if ( !defined($ID{$id}) ) {
      push @{ $ID{$id} }, @line ;
    } else {
      my @paired = pairwise { "$a  $b" } @{ $ID{$id} }, @line;
      print join("\t", $id, @paired), "\n";
      delete $ID{$id};
    };
};

$idMN의 parseline서브루틴은 전역 변수를 사용하는 대신 각 행의 ID 및 요소 배열을 반환하도록 수정되었습니다.

$id%ID구문 분석된 각 행의 해시를 저장하기 위한 키로 사용됩니다. 주어진 을 처음 볼 때 구문 분석된 행 배열( )을 해시에 $id저장 하고 다음 행으로 이동합니다. @line다음에 이를 볼 때 저장된 배열을 현재 @line배열과 쌍으로 연결하고 TAB 필드 구분 기호를 사용하여 인쇄한 다음 해시 $id에서 %ID제거합니다 .

man List::MoreUtils이 기능의 작동 방식에 대한 pairwise자세한 내용은 리소스를 참조하세요 . 그런데 List::Util및 는 List::MoreUtils다양한 목록(배열이라고도 함) 작업을 수행하기 위한 두 가지 훌륭한 모듈입니다.

산출:

$ ./zara.pl zara.txt  
1   1  2    1  1    1  1    2  2    2  1
2   2  1    2  1    2  1    2  2    1  2
3   2  1    1  1    1  1    2  2    1  2

관련 정보