8개의 열과 수백만 개의 행이 있는 CSV 파일(필드 구분 기호가 실제로 쉼표임)이 있습니다. 예는 다음과 같습니다.
1000024447,38111220,201705,181359,0,12,1,3090
1064458324,38009543,201507,9,0,1,1,1298
1064458324,38009543,201508,9,0,2,1,90017
주어진 열에 있는 모든 숫자의 합계와 읽은 행 수를 인쇄하는 가장 빠른 방법은 무엇입니까? 무엇이 더 빨라지는지 설명해 주실 수 있나요?
답변1
$ datamash -t, count 3 sum 3 < file
3,604720
일부 테스트
$ time gawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
604720000000 3000000
real 0m2.851s
user 0m2.784s
sys 0m0.068s
$ time mawk -F',' '{ sum += $3 } END{ print sum, NR }' longfile
6.0472e+11 3000000
real 0m0.967s
user 0m0.920s
sys 0m0.048s
$ time perl -F, -nle '$sum += $F[2] }{ print "$.,$sum"' longfile
3000000,604720000000
real 0m3.394s
user 0m3.364s
sys 0m0.036s
$ time { cut -d, -f3 <longfile |paste -s -d+ - |bc ; }
604720000000
real 0m1.679s
user 0m1.416s
sys 0m0.248s
$ time datamash -t, count 3 sum 3 < longfile
3000000,604720000000
real 0m0.815s
user 0m0.716s
sys 0m0.036s
따라서 mawk
, 및 datamash
가 무리 중 최선의 선택인 것으로 보입니다.
답변2
Awk
텍스트 파일 처리를 위한 빠르고 고성능 도구입니다.
awk -F',' '{ sum += $3 }
END{ printf "Sum of 3rd field: %d. Total number of lines: %d\n", sum, NR }' file
예제 출력:
Sum of 3rd field: 604720. Total number of lines: 3
개념 노트: 이러한 모든 비 대안은 "이상적인" 숫자 열에 대해서만 더 빠르게 실행된다는
점에 유의해야 합니다 . awk
약간 더 복잡한 형식(예: 계산 전에 제거할 몇 가지 추가 정보 <1064458324:a,<38009543:b,<201507:c,<9:d,<0:e,<1:f,<1:g,1298
)만 있으면 이러한 속도 이점이 모두 사라집니다(처리가 필요하지 않은 일부 이점은 말할 것도 없습니다).
답변3
추출 필드를 사용 하고 cut
숫자 사이에 paste
기호를 삽입 하고 합산할 수 있습니다. 이를 사용하여 행 수를 계산할 수 있습니다.+
bc
wc
하지만 수백만 행에 대한 성능이 어떤지 잘 모르겠습니다. 하지만 성능의 황금률은 추측하지 말고 측정하는 것입니다. 모든 솔루션을 분석하여 필요한 성능을 제공하는지 확인하고 변경 사항으로 인해 성능이 향상되거나 저하되는지 여부와 그 정도를 판단해야 합니다.
다음은 주어진 필드를 합산하고 행 수를 인쇄하는 솔루션입니다.
echo -n "Sum: "
cut -d, -f3 <file |paste -s -d+ |bc
echo -n "Lines: "
wc -l <file
산출:
Sum: 604720
Lines: 3
이 필드는 여기서 -f#
to 매개변수로 지정됩니다 .cut
cut -f3