소스 파일 :
H
T
|~^
입력 파일 샘플
R로 시작하는 입력 레코드에는 원본 소스 파일에 여러 필드가 있습니다. 여기에서는 샘플의 5 개 필드를 언급했습니다.
트레일러 레코드 세 번째 열에는 레코드 수가 있고 다섯 번째 열은 금액 열의 합계입니다 (세 번째 열 또는 레코드 줄)
분할 후에는 개수 및 합계 열이있는 아래 형식으로 새 파일에 트레일러를 추가해야합니다.
R로 시작하는 INPUT 레코드는 날짜 순서 순서를 따르지 않습니다. 예 : 1st rec는 2019-03-05 rec이 있고 마지막 기록도 같은 날짜입니다.
노트:
R로 시작하는 INPUT 레코드에는 여러 열에 날짜 필드가 있으므로 분할을 위해 세 번째 날짜 필드를 고려하십시오.
또한 날짜 필드의 타임 스탬프를 무시하십시오 . 날짜 만 고려하고 날짜 만 기준으로 분할을 수행 할 수 있습니다. 이상적으로는 세 번째 열에있는 모든 동일한 날짜의 트랜잭션을 새 파일로 이동하고 합계 및 개수와 함께 헤더 / 트레일러를 추가해야합니다. **** EDIT ****** 내 질문은 동일하게 유지되지만 금액 필드가 매우 큰 경우 (금액 필드 데이터 유형이 소수점이 최대 5 포인트가 될 수있는 Number (31,5)라고 생각해보십시오. 소수점 이하 5 자리 만있는 금액이있는 경우 매번 (31,5)가되는 것은 아닙니다. 그러면 값은 소수점 이하 5 자리까지입니다.)
입력 파일:
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^8|~^xxx|~^123670130.37256
예상 출력
파일 1 : 다음으로 저장해야합니다. 20190305.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^4|~^xxx|~^107707.068
파일 2 : 다음으로 저장해야합니다. 20190306.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
T|~^20200425|~^4|~^xxx|~^123562423.30456
awk
해결책은 다음과 같습니다 .
awk -F'\\|~\\^' '{
if($1=="H"){
head=$0
}
else if($1=="T"){
foot=$1"|~^"$2
foot4=$4
}
else{
date=$3;
sub("T.*","", date);
data[date][NR]=$0;
sum[date]+=$4;
num[date]++
}
}
END{
for(date in data){
file=date".txt";
gsub("-","",file);
print head > file;
for(line in data[date]){
print data[date][line] > file
}
printf "%s|~^%.3f|~^%s|~^%.3f\n", foot, num[date],
foot4, sum[date] > file
}
}' file
예제 데이터에서 실행하면 다음이 생성됩니다.
$ cat 20190305.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-05T12:33:52.27|~^105603.042|~^2018-10-23T12:33:52.27|~^aus
R|~^abc|~^2019-03-05T12:33:52.27|~^2054.026|~^2018-10-24T12:33:52.27|~^usa
R|~^abc|~^2019-03-05T12:33:52.27|~^30.00|~^2018-08-05T12:33:52.27|~^ddd
R|~^abc|~^2019-03-05T12:33:52.27|~^20.00|~^2018-07-23T12:33:52.27|~^audg
T|~^20200425|~^4.000|~^xxx|~^107707.068
$ cat 20190306.txt
H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^123562388.23456|~^2018-04-12T12:33:52.27|~^hhh
R|~^abc|~^2019-03-06T12:33:52.27|~^10.00|~^2018-09-11T12:33:52.27|~^virginia
R|~^abc|~^2019-03-06T12:33:52.27|~^15.03|~^2018-10-23T12:33:52.27|~^jjj
R|~^abc|~^2019-03-06T12:33:52.27|~^10.04|~^2018-04-08T12:33:52.27|~^jj
T|~^20200425|~^4.000|~^xxx|~^123562423.305
또한 awk가 느리다고 생각하는 것 같기 때문에 대용량 파일에서 테스트했습니다. 내 테스트 파일을 만들기 위해 다음을 실행했습니다.
perl -e '@d=<>; print $d[0]; $str=join("",@d[1..$#d-1]); print $str x 3500000; print $d[$#d]' file > bigFile
이렇게하면 28000002 줄의 1.9G 파일이 생성됩니다. 여기서 첫 번째 줄은 원본 파일의 헤더이고 마지막 줄은 원본의 바닥 글이며 그 사이의 줄은 원본 파일 콘텐츠의 350 만 반복입니다. 그런 다음이 파일에 대해 awk를 실행했습니다 (이에 충분한 RAM이 있으므로 최소 618M의 여유 RAM이 필요합니다).
$ time awk -F'\\|~\\^' '{ if($1=="H"){head=$0} else if($1=="T"){foot=$1"|~^"$2; foot4=$4;} else{date=$3; sub("T.*","", date);data[date][NR]=$0;sum[date]+=$4;num[date]++;} }END{for(date in data){file=date;gsub("-","",file); sub("T.*",".txt",file); print head > file; for(line in data[date]){print data[date][line] > file} printf "%s|~^%s|~^%s|~^%s\n", foot, num[date], foot4, sum[date] > file } }' bigFile
real 2m8.603s
user 2m0.610s
sys 0m6.795s
따라서 28,000,002 라인에서 1.9G의 데이터를 처리하는 데 2 분이 걸립니다. 그것은 꽤 빠릅니다 ( Isaac의 솔루션 은 1m 30에서 더 빠르고 메모리를 덜 사용하므로 UI는 대신 사용하는 것이 좋습니다). 셸 for
루프를 사용하면 이렇게 빨리 얻을 수 없을 것 입니다. 또한 R for 루프도 마찬가지입니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다