아래와 같이 큰 파일이 있습니다.
chr10 98072 1
chr10 98073 1
chr10 98074 1
chr10 98075 2
chr10 98076 2
chr10 98077 3
chr10 98078 5
chr10 98079 5
chr11 98080 5
chr12 98081 5
각 염색체마다 많은 항목이 있습니다. chr10이 포함된 행만 추출하고 싶습니다. 내 파일이 크기 때문에 이 명령을 사용하여 chr10 줄만 추출합니다.
awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt
awk가 전체 파일을 반복하지 않도록 하는 좋은 방법입니까? 내 파일은 염색체에 따라 정렬되었습니다.
감사해요
답변1
awk '$1=="chr10"{print; next}{exit}' cov.txt > subset.txt
테스트: /dev/null
다음 으로 리디렉션12,947,909 chr10
기록에 더해 총 몇 가지 기록 chr11
추가chr12
99,063,774행 - 출력은 모두 동일합니다(동일한 md5sum). 출력 라인 수 =12,947,909-- 가장 빠른 것부터 가장 느린 것까지 정렬:
스티브:awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt >/dev/null
real 0m5.963s
user 0m5.896s
sys 0m0.064s
피터 오:awk '$1=="chr10"{print; next}{exit}' cov.txt >/dev/null
real 0m6.553s
user 0m6.484s
sys 0m0.068s
코스:perl -pe '!/chr10/&&exit' cov.txt >/dev/null
real 0m8.658s
user 0m8.545s
sys 0m0.112s
스티브:sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt >/dev/null
real 0m17.130s
user 0m17.077s
sys 0m0.052s
사용자 3138373:awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt >/dev/null
real 0m18.621s
user 0m18.541s
sys 0m0.080s
답변2
이것을 시도해 보세요. 기본 테스트에서는 조금 더 빠른 것 같습니다. 정규식 처리를 피하세요.
[root@localhost tmp]# wc -l cov.txt
34970568 cov.txt
[root@localhost tmp]# time awk '$1 ~ /^chr10$/{print}; $1 !~ /^chr10$/{exit}' cov.txt > subset.txt
real 0m23.897s
user 0m22.031s
sys 0m1.556s
[root@localhost tmp]# time awk '{ if($1 == "chr10") { print } else { exit } }' cov.txt > subset.txt
real 0m16.784s
user 0m14.731s
sys 0m1.661s
[root@localhost tmp]#
또한 lcd047 타이밍의 sed 방법을 시도했습니다.
[root@localhost tmp]# time sed -n '/^chr10[^0-9]/ { p; b; }; q' cov.txt > subset.txt
real 0m38.343s
user 0m36.609s
sys 0m1.546s
[root@localhost tmp]#
전체 파일을 읽더라도 일반 오래된 grep을 사용하는 것이 가장 빠릅니다.
[root@localhost tmp]# time grep "^chr10" cov.txt >subset.txt
real 0m6.546s
user 0m4.932s
sys 0m1.577s
[root@localhost tmp]#
나는 grep -F가 다시 더 빨라질 것이라고 생각했지만 그렇지 않은 것 같습니다. 7초 이상 지속됩니다.
[root@localhost tmp]# time grep -F chr10 cov.txt >subset.txt
real 0m7.317s
user 0m6.109s
sys 0m1.173s
[root@localhost tmp]#
답변3
보다 효율적으로 다음을 수행하십시오 egrep
.
egrep '^chr10{space or tab}' cov.txt
또는 콘텐츠가 귀하가 보여주고 있는 것과 유사하다면,
grep -w chr10 cov.txt
답변4
파일이 정렬되어 있으므로귀하의 의견Perl로 시작하는 줄은 chr10
항상 파일의 시작 부분에 있습니다.
< cov.txt perl -pe '!/chr10/&&exit' > subset.txt
이렇게 하면 첫 번째 불일치 시 스크립트가 종료됩니다.
메모리에 저장된 1,000,000개의 일치하는 라인이 있는 파일 chr10 98072 1
에 대한 테스트 실행 (빈 파일에 라인을 1,000,000번 추가하여 얻은 결과)은 즉시 실행됩니다.
~/tmp$ < cov.txt wc -l
1000000
~/tmp$ time < cov.txt perl -pe '!/chr10/&&exit' > subset.txt
real 0m0.631s
user 0m0.624s
sys 0m0.004s
~/tmp$ < subset.txt wc -l
1000000