펄 솔루션:

펄 솔루션:

이것은 처리할 스크립트를 찾고 싶은 두 가지 일반적인 구분 텍스트 파일 변환 문제입니다( 이 작업에 awk가장 적합한 지는 모르겠습니다 ).perl

csh내 Solaris 10 Unix 서버의 기본 셸이므로 csh또는 셸과 함께 작동하는 솔루션이 sh선호됩니다.

질문 1:

File1.dat다음 과 같은 2개의 구분된 ASCII 파일이 있습니다.File2.dat

File1.dat(맵 파일):

1|A  
2|B  
3|C  
4|D  
5|E  
6|F  
.  
.  
.  
26|Z  
27|Who  
28|What  
29|Where

파일 2.dat

Field1|Field2|Field3  
1|John|20120101  
3|Amy|20120103  
6|Larry|20120104  
3|Kevin|20120203  
8|Fred|20120623  
4|Mary|20120728  
26|Eric|20120819  
28|Larry|20120917

File1.dat에 표시된 지도를 사용하여 아래와 같은 File2.dat세 번째 파일 로 변환하고 싶습니다 . File3.dat기본적으로 File1.dat의 매핑을 사용하여 파일에 새 열을 생성/채워서 결국 새로 변환된 파일에 다음과 같은 4개의 열이 있게 됩니다.

파일 3.dat

Field1|Field2|Field3|Field4  
1|A|John|20120101  
3|C|Amy|20120103  
6|F|Larry|20120104  
3|C|Kevin|20120203  
8|H|Fred|20120623  
4|D|Mary|20120728  
26|Z|Eric|20120819  
28|What|Larry|20120917

질문 2:

다음과 같은 공통 항목이 있는 일련의 레코드 중 첫 번째 레코드(정렬된 일련의 레코드)만 유지하고 싶습니다. [필드 2, 필드 3, 필드 4는 레코드에서 동일한 값을 가짐]

다음과 같은 초기 구분 파일 File1.dat가 있습니다(15개 레코드, 각 레코드에는 4개 필드가 있음). 왼쪽은 파일의 일부가 아니며, 진행 상황을 추적할 수 있는 레코드 #일 뿐입니다.

파일 1.dat

    Field1|Field2|Field3|Field4
1.    20120227|Andy|101|34  
2.    20120315|Andy|101|34  
3.    20120415|Andy|101|36  
4.    20120417|Andy|103|37  
5.    20120417|Andy|103|37  
6.    20120227|Jane|101|34  
7.    20120315|Jane|101|34  
8.    20120415|Jane|101|36  
9.    20120417|Jane|103|37  
10.   20120417|Jane|103|37  
11.   20120227|Bob|101|34  
12.   20120315|Bob|101|34  
13.   20120415|Bob|101|36  
14.   20120417|Bob|103|37  
15.   20120417|Bob|103|37

File1.dat15개의 레코드가 포함된 이 파일() 을 아래와 같이 새 파일() 로 변환하고 싶습니다 (이 9개의 레코드만 유지).File2.dat

보시다시피 중복 File1.dat레코드의 정의가 [Field2 & Field3 & Field4는 2개 이상의 레코드에서 동일한 값을 가짐]과 동일한 경우 중복 레코드를 제거합니다.

파일 2.dat

1.   20120227|Andy|101|34
3.   20120415|Andy|101|36
4.   20120417|Andy|103|37
6.   20120227|Jane|101|34
8.   20120415|Jane|101|36
9.   20120417|Jane|103|37
11.  20120227|Bob|101|34
13.  20120415|Bob|101|36
14.  20120417|Bob|103|37

결론적으로:

솔루션 코드에서 다음 두 가지 사항이 해결되는 위치를 알려주십시오.

a) 내 파일의 구분 기호는 파이프 |문자 입니다
. b) 코드의 어느 부분이 Field1, Field2, Field3, Field4 등을 참조합니까?

답변1

펄 솔루션:

질문 1.

File1.dat는 해시로 읽혀지며 첫 번째 열은 키이고 두 번째 열은 값입니다. 그런 다음 File2.dat가 처리되고 해시의 값이 첫 번째 열(Perl의 경우 열 0)에서 가져온 키를 기반으로 행의 값을 나타내는 배열에 삽입됩니다.

#!/usr/bin/perl
use warnings;
use strict;

my %tab;

open my $F1, '<', 'File1.dat' or die $!;
while (<$F1>) {
    chomp;
    my ($key, $value) = split /\|/; # Here, the delimiter is mentioned.
    $tab{$key} = $value;
}

open my $F2, '<', 'File2.dat' or die $!;
while (<$F2>) {
    chomp;
    my @cols = split /\|/;
    splice @cols, 1, 0, $tab{$cols[0]};
    print join('|', @cols), "\n";
}

표준 유틸리티를 사용하여 유사한 출력을 얻을 수 있습니다.

join -a2 -t'|' <(sort File1.dat) <(sort File2.dat) | sort -n

질문 2.

해시에서 이미 본 필드 조합을 기억하세요. 새로운 조합이면 해당 행을 인쇄하고, 그렇지 않으면 아무 작업도 수행하지 않습니다.

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

my %seen;
while (<>) {
    chomp;
    my @fields = split /\|/, $_, 2;          # Only split into 2 fields.
    say unless exists $seen{$fields[1]};     # Do not print if already seen.
    undef $seen{$fields[1]};                 # Mark the key as seen.
}

관련 정보