![대용량 파일과 일치하도록 입력 파일의 패턴 발생 횟수를 계산합니다.](https://linux55.com/image/120940/%EB%8C%80%EC%9A%A9%EB%9F%89%20%ED%8C%8C%EC%9D%BC%EA%B3%BC%20%EC%9D%BC%EC%B9%98%ED%95%98%EB%8F%84%EB%A1%9D%20%EC%9E%85%EB%A0%A5%20%ED%8C%8C%EC%9D%BC%EC%9D%98%20%ED%8C%A8%ED%84%B4%20%EB%B0%9C%EC%83%9D%20%ED%9A%9F%EC%88%98%EB%A5%BC%20%EA%B3%84%EC%82%B0%ED%95%A9%EB%8B%88%EB%8B%A4..png)
텍스트 파일에 대학 목록이 있고, 별도의 파일에 소속이 있는 출판물 목록이 있습니다. 출판물이 몇 번이나 반복되는지 확인하고 대학 공동 작업 횟수를 계산하는 스크립트를 작성하고 싶습니다. 제가 작성한 데이터는 다음과 같습니다. "p1"은 논문 제목이고, "소속 기관"은 논문이 게재된 기관입니다.
예:-
데이터
UID, 소속
p1 "ADPRI, S"
p1 "ADPRI, S"
p2 "ADPRI, S"
p2 "AAC&S, H"
p3 "AAC&S, H"
p3 "HU, USA"
p3 "Penn, USA"
p4 "AAC&S, H"
p5 "AAC&S, H"
p6 "AAC&S, H"
p7 "AAC&S, H"
p8 "AU, A"
p9 "AECI, A"
p10 "AECI, A"
p10 "AECI, A"
위 데이터에서 논문 "p2"는 "ADPRI,S" 및 "AAC&S,H"에 연결되어 있습니다.
마찬가지로 "p3"은 대학 "AAC&S, H", "HU, USA", "Penn, USA"로 연결됩니다.
따라서 내 스크립트는 두 대학 간의 협력 횟수를 제공하는 파일을 제공해야 합니다. 위의 데이터는
원하는 출력:
College_A College_B Collaborated
ADPRI, S AAC&S, H 2
HU, USA Penn, USA 1
....
....
so on for all the colleges,
**"열 2"에서 sort 및 uniq 명령을 사용하여 대학 수를 얻었습니다. 이는 797개 대학 목록이며 내 데이터베이스에는 해당 대학에서 출판한 20,000개 이상의 논문이 있습니다. 내 데이터에도 공백과 특수 문자가 많이 있습니다. **
추신:- 데이터는 탭으로 구분되어 있으며 동일한 데이터가 CSV에 있습니다.
답변1
펄 사용:
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils qw(uniq);
use Set::Intersection;
my ( %papers, @colleges );
while (<>) {
chomp;
my ( $paper, $college ) = m/(\S+)\t"(.+)"/g;
# normalize college names
$college =~ s/\s\+/ /go;
$college =~ s/^\s\+//go;
$college =~ s/\s\+$//go;
$papers{$college} //= [];
push @{ $papers{$college} }, $paper;
}
@colleges = sort keys %papers;
for my $college (@colleges) {
$papers{$college} = [ uniq sort @{ $papers{$college} } ];
}
print qq(College_A\tCollege_B\tCollaborated\n);
for ( my $i = 0 ; $i < @colleges - 1 ; $i++ ) {
for ( my $j = $i + 1 ; $j < @colleges ; $j++ ) {
my $collaborations = scalar get_intersection(
{ -preordered => 1 },
$papers{ $colleges[$i] },
$papers{ $colleges[$j] }
);
print $colleges[$i], "\t", $colleges[$j], "\t", $collaborations, "\n"
if ($collaborations);
}
}
Python 사용:
#!/usr/bin/env python
from __future__ import print_function
import re
import sys
from collections import defaultdict
papers = defaultdict(lambda: set())
for line in sys.stdin:
paper, college = line.split("\t")
college = re.sub(r'^"|"$', '', college)
college = re.sub(r'\s+', ' ', college)
college = re.sub(r'^\s+|\s+$', '', college)
papers[college].add(paper)
colleges = sorted(papers.keys())
print("College_A\tCollege_B\tCollaborated")
for i in range(len(colleges) - 1):
for j in range(i + 1, len(colleges)):
collaborations = len(papers[colleges[i]].intersection(papers[colleges[j]]))
if collaborations:
print("%s\t%s\t%d" % (colleges[i], colleges[j], collaborations))
답변2
gawk
해결책.
용법: ./program.awk input.txt
또한 ./program.awk input.txt | column -t -s $'\t'
정렬이 손실된 경우 다음을 수행할 수 있습니다. 멋진 표시를 위해.
#!/usr/bin/awk -f
function pub_to_aff() {
for(i in pub_arr) {
for(j in pub_arr) {
if(i != j)
aff_arr[i][j]++;
}
}
delete pub_arr;
}
BEGIN {
OFS = "\t";
FS = "\t";
}
$1 != prev_uid {
prev_uid = $1;
pub_to_aff();
}
{
pub_arr[$2] = 1;
}
END {
pub_to_aff();
print "College_A", "College_B", "Collaborated";
for(i in aff_arr) {
for(j in aff_arr[i]) {
print i, j, aff_arr[i][j];
}
}
}
입력하다- 데모를 위해 두 줄을 추가했습니다 - to p3
및 p4
.
p1 "ADPRI, S"
p1 "ADPRI, S"
p2 "ADPRI, S"
p2 "AAC&S, H"
p3 "AAC&S, H"
p3 "ADPRI, S"
p3 "HU, USA"
p3 "Penn, USA"
p4 "AAC&S, H"
p4 "ADPRI, S"
p5 "AAC&S, H"
p6 "AAC&S, H"
p7 "AAC&S, H"
p8 "AU, A"
p9 "AECI, A"
p10 "AECI, A"
p10 "AECI, A"
산출
College_A College_B Collaborated
"AAC&S, H" "HU, USA" 1
"AAC&S, H" "Penn, USA" 1
"AAC&S, H" "ADPRI, S" 3
"HU, USA" "AAC&S, H" 1
"HU, USA" "Penn, USA" 1
"HU, USA" "ADPRI, S" 1
"Penn, USA" "AAC&S, H" 1
"Penn, USA" "HU, USA" 1
"Penn, USA" "ADPRI, S" 1
"ADPRI, S" "AAC&S, H" 3
"ADPRI, S" "HU, USA" 1
"ADPRI, S" "Penn, USA" 1
편집 - 실제 데이터 테스트.
입력하다- 샘플.txt 콘텐츠의 일부만 남겨두고 스크립트 작동을 보여주기 위해 몇 줄을 변경했습니다. 입력 파일에 파트너 대학이 포함되어 있지 않으면 스크립트는 헤더라는 한 줄만 출력합니다.
WOS:000355337800046 "ACHARYA NARENDRA DEV COLL, NEW DELHI"
WOS:000355337800046 "ACHARYA NARENDRA DEV COLL, NEW DELHI"
WOS:000355337800046 "ACHARYA PRAFULLA CHANDRA COLL. KOLKATA"
WOS:000328700900001 "ACHARYA PRAFULLA CHANDRA COLL. KOLKATA"
WOS:000338233800012 "ADAMAS INST TECHNOL, KOLKATA"
WOS:000338233800012 "ADARSH MAHAVIDYALAYA DHAMANGAON RAILWAY, AMRAVATI"
WOS:000349637600009 "ADARSH MAHAVIDYALAYA DHAMANGAON RAILWAY, AMRAVATI"
WOS:000314892400031 "ADITYA INST TECHNOL & MANAGEMENT, TEKKALI"
사용된 명령: ./program.awk sample.txt | column -t -s $'\t'
산출
College_A College_B Collaborated
"ADAMAS INST TECHNOL, KOLKATA" "ADARSH MAHAVIDYALAYA DHAMANGAON RAILWAY, AMRAVATI" 1
"ACHARYA NARENDRA DEV COLL, NEW DELHI" "ACHARYA PRAFULLA CHANDRA COLL. KOLKATA" 1
"ACHARYA PRAFULLA CHANDRA COLL. KOLKATA" "ACHARYA NARENDRA DEV COLL, NEW DELHI" 1
"ADARSH MAHAVIDYALAYA DHAMANGAON RAILWAY, AMRAVATI" "ADAMAS INST TECHNOL, KOLKATA" 1