일치하지 않는 모든 패턴을 출력하려면 다음 grep 스크립트를 사용합니다.
grep -oFf patterns.txt large_strings.txt | grep -vFf - patterns.txt > unmatched_patterns.txt
패턴 파일에는 다음과 같은 12자 길이의 하위 문자열이 포함되어 있습니다(몇 가지 예가 아래에 표시되어 있음).
6b6c665d4f44
8b715a5d5f5f
26364d605243
717c8a919aa2
Large_strings 파일에는 약 2~1억 자 길이의 매우 긴 문자열이 포함되어 있습니다(문자열의 작은 부분이 아래에 표시됨).
121b1f212222212123242223252b36434f5655545351504f4e4e5056616d777d80817d7c7b7a7a7b7c7d7f8997a0a2a2a3a5a5a6a6a6a6a6a7a7babbbcbebebdbcbcbdbdbdbdbcbcbcbcc2c2c2c2c2c2c2c2c4c4c4c3c3c3c2c2c3c3c3c3c3c3c3c3c2c2c1c0bfbfbebdbebebebfbfc0c0c0bfbfbfbebebdbdbdbcbbbbbababbbbbcbdbdbdbebebfbfbfbebdbcbbbbbbbbbcbcbcbcbcbcbcbcbcb8b8b8b7b7b6b6b6b8b8b9babbbbbcbcbbbabab9b9bababbbcbcbcbbbbbababab9b8b7b6b6b6b6b7b7b7b7b7b7b7b7b7b7b6b6b5b5b6b6b7b7b7b7b8b8b9b9b9b9b9b8b7b7b6b5b5b5b5b5b4b4b3b3b3b6b5b4b4b5b7b8babdbebfc1c1c0bfbec1c2c2c2c2c1c0bfbfbebebebebfc0c1c0c0c0bfbfbebebebebebebebebebebebebebdbcbbbbbab9babbbbbcbcbdbdbdbcbcbbbbbbbbbbbabab9b7b6b5b4b4b4b4b3b1aeaca9a7a6a9a9a9aaabacaeafafafafafafafafafb1b2b2b2b2b1b0afacaaa8a7a5a19d9995939191929292919292939291908f8e8e8d8c8b8a8a8a8a878787868482807f7d7c7975716d6b6967676665646261615f5f5e5d5b5a595957575554525
위 스크립트(gnu 병렬, xargs, fgrep 등)의 속도를 어떻게 높일 수 있습니까? --pipepart 및 --block을 사용해 보았지만 두 개의 grep 명령을 파이프할 수 없습니다.
그건 그렇고, 이것들은 16진수 문자열과 패턴입니다.
답변1
이것은 작동합니다:
parallel --pipepart --block -1 -a large_strings.txt grep -oFf patterns.txt |
grep -vFf - patterns.txt > unmatched_patterns.txt
사용한 적이 있는 경우 ripgrep
:
parallel --pipepart --block -1 -a large_strings.txt rg -oFf patterns.txt |
rg -vFf - patterns.txt > unmatched_patterns.txt
크기도 크면 patterns.txt
다음을 살펴보세요.
https://www.gnu.org/software/parallel/man.html#예: -Grepping-n-lines-for-m-regular-expressions
귀하의 상황은 BLAT가 DNA를 위해 만들어졌다는 점을 제외하면 BLAT가 해결하는 문제와 매우 유사합니다. 하지만 귀하의 경우에는 BLAT를 사용할 수 없을 것 같습니다. 일부 변경이 필요할 수도 있습니다.할 수 있다각 16진수 값을 2개의 DNA 문자로 변환하여 직접 사용하세요. BLAT는 데이터베이스 조회만큼 빠르기 때문에 grep
.
http://genome.ucsc.edu/FAQ/FAQblat.html#blat3
답변2
grep이 없는 더 효율적인 답변:
build_k_mers() {
k="$1"
slot="$2"
perl -ne 'for $n (0..(length $_)-'"$k"') {
$prefix = substr($_,$n,2);
$fh{$prefix} or open $fh{$prefix}, ">>", "tmp/kmer.$prefix.'"$slot"'";
$fh = $fh{$prefix};
print $fh substr($_,$n,'"$k"'),"\n"
}'
}
export -f build_k_mers
rm -rf tmp
mkdir tmp
export LC_ALL=C
# search strings must be sorted for comm
parsort patterns.txt | awk '{print >>"tmp/patterns."substr($1,1,2)}' &
# make shorter lines: Insert \n(last 12 char before \n) for every 32k
# This makes it easier for --pipepart to find a newline
# It will not change the kmers generated
perl -pe 's/(.{32000})(.{12})/$1$2\n$2/g' large_strings.txt > large_lines.txt
# Build 12-mers
parallel --pipepart --block -1 -a large_lines.txt 'build_k_mers 12 {%}'
# -j10 and 20s may be adjusted depending on hardware
parallel -j10 --delay 20s 'parsort -u tmp/kmer.{}.* > tmp/kmer.{}; rm tmp/kmer.{}.*' ::: `perl -e 'map { printf "%02x ",$_ } 0..255'`
wait
parallel comm -23 {} {=s/patterns./kmer./=} ::: tmp/patterns.??
저는 이것을 전체 작업( patterns.txt
:9GBytes/725937231 라인, large_strings.txt
:19GBytes/184 라인)에서 테스트했고 64코어 컴퓨터에서 3시간 만에 완료했습니다.
답변3
이것이 효과가 있는지 모르겠습니다 ...
while read line;
do
grep -oF "$line" large_strings.txt &
done <patterns.txt | grep -vFf - patterns.txt > unmatched_patterns.txt