나는 열 166 이후의 열 헤더를 가져와 이를 각 후속 행에 인쇄하는 awk 스크립트를 사용하고 있습니다.
전임자.
col165 col166 col167
a 1 2
b 3 4
c 5 6
이 되다--
col165 col166 col167
a col166|1 col167|2
b col166|3 col167|4
c col166|5 col167|6
그런데 제가 작업하고 있는 파일은 꽤 크며(약 160만 줄) 처리하는데 약 1.5시간이 걸립니다.
프로세스 속도를 높이기 위해 대용량 파일을 100,000개 라인으로 분할한 다음 gnu를 사용하여 parallel
각 파일을 개별적으로 처리하는 방법을 생각했습니다. 그러나 파일의 헤더를 가져와 헤더를 가져오는 데 사용하는 스크립트에 문제가 발생했습니다. 헤더를 지정하기 위해 다른 파일을 사용하고 싶습니다. 그렇지 않으면 각 분할 파일에 헤더를 추가해야 합니다(그 자체로는 번거로워 보입니다).
내가 사용하는 코드는 -
awk 'BEGIN { FS="\t";OFS="\t" };
NR == 1 { split($0, headers); print; next }
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' input > output
column_headers
파일을 사용하여 제목을 지정 하고 싶습니다 . 가능합니까?
다음 코드를 시도했지만 작동하지 않으며 코드가 올바른지 확실하지 않습니다.
awk -v head='$(cat column_headers)' 'BEGIN{ FS="\t";OFS="\t" };
NR == 1 { split($head, headers); print; next }
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' input > output
내가 뭔가 잘못하고 있는 것 같은 느낌이 들지만 무엇인지 잘 모르겠습니다. 제가 받을 수 있는 어떤 도움이라도 감사하겠습니다.
편집: 감사합니다. 실제로 장기적인 범인이었던 체인의 또 다른 명령을 놓쳤습니다.
@Ole Tange가 언급했듯이 명령을 사용했지만 약간 수정했습니다.
time cat input_1|parallel -k -q -j 24 --tmpdir tmp/ --block 900M --pipe awk -f culprit_script > output
스크립트는 기본적으로 각 필드를 분할하고 값에 따라 제거/유지합니다.
첫 번째 명령을 실행하는 데 약 15~20분이 걸렸고, 두 번째 스크립트는 한 시간 남짓 걸렸습니다. 병렬성과 24스레드를 활용하여 7분만에 완료! 첫 번째 명령에도 병렬성을 사용할 것 같아요 :P
모든 분들의 의견과 제안에 감사드립니다!
답변1
실제로 답변은 아니지만 너무 크고 서식이 필요하므로 주석이 될 수 없으므로 ...
1.6M은 많은 행 수가 아닙니다. 말씀하신 대로 시간당 100만 행이 표시됩니다.대규모로느리다면 분당 100만 행이 더 합리적입니다. 예를 들어 다음 스크립트를 실행하여 한 줄에 300개의 열이 있는 1,600,000줄의 파일을 만들었습니다.
$ awk -v n=1600000 -v c=300 -v OFS='\t' 'BEGIN{for (j=1;j<=c;j++) printf "col%s%s",j,(j<c?OFS:ORS); for (i=1;i<=n;i++) for (j=1;j<=c;j++) printf "%s%s",j,(j<c?OFS:ORS)}' > file
그런 다음 정기적으로 스크립트를 실행하여 문제의 파일을 변환합니다.
$ time awk 'BEGIN{FS=OFS="\t"} NR==1{split($0, headers); print; next} {for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1' file > out
real 1m22.569s
user 1m17.971s
sys 0m4.359s
따라서 실행 시간은 1.5시간이 아닌 약 82초입니다.
답변2
GNU Parallel의 경우 다음과 같습니다.
#!/bin/bash
do_block() {
awk 'BEGIN{FS=OFS="\t"}
NR==1{split($0, headers); next}
{for (i=166;i<=NF;i++) $i=headers[i] "|" $i } 1'
}
export -f do_block
# Non-parallel version
cat file | head -n1 > out1
time cat file | do_block >> out1
# Parallel version
cat file | head -n1 > out2
time parallel -k --pipepart --block -30 -a file --header : do_block >> out2
내 4코어 CPU에서는 병렬 버전이 약 3배 더 빠릅니다.