2つのファイルAとBがあります。Aは次のようになります(4〜6行):
GAGA
CAGA
GGGT
TATT
ファイルBは数千行の非常に大きなファイルです。短い例を次に示します。
AAATGTCAAGAGACAGAAATGTCAAGAGGGT
AAGGGGGTTTATAATCATAAATCAAAGAAAT
ATATACAGAAATGTCAAGAGACAGAAATGTC
TCAAGAGACAGAAATGTCAAGAGGGTCTATA
AAGAGGGTCTATAATCATAAATCAAAGAAAT
AAGAGGGTCTATAATCATAAATCAAAGAAAT
ATACAGAAATGTCAAAACAGAAATGTCAAGG
ATATACAGAATATACAGAAATGTCAAGTTAT
ACAGAATATACAGAAATGTCAAGTTATATAC
ATATACAGAAATGTCAAGAGACAGAAATGTC
TCAGAATATAGTATTCTATTATATACAGAAA
AATATAGTATTCTATTATATACAGAAATGTC
GAATATACAGAAATGTCAAGTTATATACAGA
TATACAGAATATAGTATTCTATTATATACAG
CAGAATATAGTATTCTATTATATACAGAATA
AGTTATATACAGAATATAGTATTCTATTATA
TACAGAATATAGTATTCTATTATATACAGAA
CAGAAATGTCAAGTTATATACAGAATATAGT
ファイルBのすべての行でファイルAのすべての文字列を検索し、Aの各文字列を含むファイルBの最初の10行を回復する必要があります。grepとawkを試しましたが、良い結果は得られませんでした。ありがとう
パターンは4〜6行しかないので、ORパターンで使用しませんか?2番目のファイル "bigDNA.txt"で動作する10個の一致に制限する例:
grep -E 'GAGA|CAGA|GGGT|TATT' -m 10 bigDNA.txt
これにより、ファイルpatt.txt
からパターンを手動で入力する手間が省けます。 |
で行を結合します(各行に|
を追加し、改行を削除し、末尾の|
を削除します):
grep -E "$(sed 's#$#|#' patt.txt | tr -d '\n' | sed 's#|$##')" -m 10 bigDNA.txt
while
ループで「ファイルA」を反復処理してみましたか?
while read string
do grep "$string" file-B | head -10
done < file-A
または1行で:
while read string; do grep "$string" file-B | head -10; done < file-A
これはうまくいけば読めるスクリプトです。
FIRSTFILEには、1行に1つのアイテムが含まれます(余分なスペースはありません)。BIGFILEには、一致させたい大きなリストが含まれています。
awk -F, '
BEGIN{
regexp="__NOTMATCHING__"
linematched=0
while(( getline line<"FIRSTFILE") > 0 ) {
nb_items[line]=0; #initialise a counter in items["...."]
regexp=regexp"|"line #we create a "egrep-like" regexp matching each item
}
}
#main : read each line.
# - save each matching lines.
# - and increment each corresponding counters.
{ if ( $0 ~ regexp ) {
matchinglines[++linematched]=$0
for ( item in nb_items ) {
#for each matching item, we also increment that item s number
if ( $0 ~ item ) {
nb_items[item]++ ;
}
}
}
}
END { #at the end, we print all items which have nb_item[item]>=10
for ( item in nb_items ) {
if (nb_items[item] >= 10) {
print "for this item:",item
for (i;i<=linematched;i++) {
if ( matchinglines[i] ~ item ) {
print matchinglines[i] ;
}
}
}
}
}
' BIGFILE
これは、任意の文字列に一致する最初の10行を印刷します。
grep -m 10 -Ff motifs sequence.fa
これは、各モチーフを読み取り、それを計算して最初の10行を印刷するため、各モチーフに対して10行を印刷します。
while read mot; do grep -m 10 "$mot" sequence.fa; done < motifs
ただし、これはDNAシーケンスのように見えます。つまり、改行は完全に任意であり、次のように一致させることができます。
ACTG[〜#〜] ga [〜#〜]
[〜#〜] ga [〜#〜]
これらのアプローチでは、上記のGAGA
は一致としてカウントされず、これはおそらくあなたが望むものではありません。代わりに、検索する前にすべてを1行に入れることをお勧めします。あなたは一致する線を求めているので、これらのモチーフのそれぞれをそのコンテキストで欲しいと思います。したがって、これを適切に行うには、改行で分割されたモチーフを一致させ、まずファイルを [〜#〜] tbl [〜#〜] 形式に変換します。私は何年も同僚(Pepに感謝)が書いた同じawk
スクリプトを使用しています。
#!/bin/sh
gawk '{
if (substr($1,1,1)==">")
if (NR>1)
printf "\n%s\t", substr($0,2,length($0)-1)
else
printf "%s\t", substr($0,2,length($0)-1)
else
printf "%s", $0
}END{printf "\n"}' "$@"
上記のスクリプトを$PATH
のどこかにFastaToTbl
として保存し(例:/usr/local/bin
)、実行可能にします(chmod a+x /usr/local/bin/FastaToTbl
)。次に、FASTA形式のシーケンスをパイプ処理するだけで、.tbl
形式を出力します。ここで、識別子とシーケンスはすべて同じ行にあります。
したがって、FastaToTbl
を設定したら、次のコマンドを実行できます。
while read mot;
do
FastaToTbl sequence.fa | grep -Po ".{10}$mot.{10}" | head -n 10
done < motifs
上記は、各パターンの最初の10個の一致を提供し、改行で分割されたモチーフにも一致します。また、一致したパターンの両側に10文字を印刷します。{10}
を別の数字に変更して、この動作を制御します。