
셸 스크립트에 대한 도움이 필요합니다. 키와 값이 포함된 약 1.2GB 데이터의 대용량 파일 2개가 있습니다. 키를 기준으로 두 파일을 비교하고 세 번째 파일의 값과 파일 1의 고유 값의 차이를 저장해야 합니다.
파일 1:
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
파일 2:
test1 polo;angus
test2 mike
test4 bob;janet
file1의 처음 두 열을 file2와 비교하고 싶습니다(처음 두 열에서 file2의 전체 내용 검색). 일치하는 경우 값의 차이를 인쇄합니다. 그런 다음 파일 1의 두 번째 줄을 검색합니다. 또한 파일 1의 고유 키도 인쇄되어야 합니다.
예상 출력:
test1 marco
test2 zen;liza
test3 tom;harry;alan
test4 june
제가 가지고 있는 파일은 약 100,000줄에 달하는 대용량이므로 실행을 빠르게 하고 싶습니다. 이것은 #!/usr/bin/env bash.
예를 들어 쉘 스크립트에서 실행됩니다.
1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule 343323H;343434311H;454656556H;343343432H
1332239_44557576_CONTI Lased & Micro kjd $353.50_30062020_lsdf3_no-rule
이는 키( ) 로, 값으로 다음을 포함하는 간단한 텍스트 파일입니다 343323H;343434311H;454656556H;343343432H
.
파일 2는 항상 파일 1의 하위 집합이 됩니다. 파일 2에 없는 값(키에 대해)과 파일 1에 있는 고유한 값을 찾으면 됩니다.
답변1
Perl 스크립트 사용:
검색 중이라고 가정file1을 기반으로 하는 file2그 반대도 아닙니다. file2를 기반으로 file1을 검색하려면 다음을 수행해야 합니다.또 다른 for 루프를 추가하세요file2 Dictionary(hash) 의 경우.
데이터 파일:
$ cat file1.txt
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
$ cat file2.txt
test1 polo;angus
test2 mike
test4 bob;janet
스크립트:
#!/usr/bin/perl
use warnings;
use strict;
my $file1=$ARGV[0];
my $file2=$ARGV[1];
my %dict1; #Stores file1 unique key and value pairs in this dictionary ( HASH in perl )
my %dict2; #Stores file2 unique key and value pairs in this dictionary ( HASH in perl )
my %output; #This is output dictionary after processing all the data to print it out
open(F1,'<',$file1) or die "File not found $file1";
open(F2,'<',$file2) or die "File not found $file2";
#Store both file's contents in %dict1 and %dict2 respectively
while(<F1>)
{
my ($key,$value) = split(/\s+/,$_);
$dict1{$key} = $value;
}
while(<F2>)
{
my ($key,$value) = split(/\s+/,$_);
$dict2{$key} = $value;
}
#Get the unique(difference) value from file2 based in the values in file1
foreach my $k ( keys %dict1 )
{
if ( defined $dict2{$k} )
{
my @dict1values=split(";",$dict1{$k});
my @dict2values=split(";",$dict2{$k});
foreach (@dict1values)
{
if ( $dict2{$k} !~ /[;]*?$_[;]*?/) {
$output{$k} .=$_.";";
}
}
} else {
$output{$k}=$dict1{$k};
}
}
foreach my $ke (sort(keys(%output)))
{
print "$ke $output{$ke}\n" if ( defined($output{$ke}) );
}
출력 :
$ ./testing.pl file1.txt file2.txt
test1 marco;
test2 zen;liza;
test3 tom;harry;alan
test4 june;
답변2
여기에앗매우 빠른 버전입니다.
요청된 필드 패턴 [string:key][space|";"][string][space|";"] 등을 따르는 모든 항목에서 작동합니다.
$ cat file1;echo "";cat file2
test1 marco;polo;angus
test2 mike;zen;liza
test3 tom;harry;alan
test4 bob;june;janet
test1 polo;angus
test2 mike
test4 bob;janet
$ awk -F '[ ;]' '
NR==FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
NR!=FNR{ for(i=2;i<=NF;i++){ k[$1,$i]++ } }
END{ for(i in k){
if(k[i]==1){
split(i,arr_i,SUBSEP);
k_e[arr_i[1]]=k_e[arr_i[1]]""arr_i[2]";"
}
}
for(i in k_e){
print i" "k_e[i]
}
}' file1 file2 | sort | sed 's/.$//'
test1 marco
test2 liza;zen
test3 harry;alan;tom
test4 june