次のTSVファイル(抽出)があります。
ファイル1:
NC_002163.1 RefSeq source 1 1641481 . + . organism=Campylobacter jejuni subsp. jejuni NCTC 11168;mol_type=genomic DNA;strain=NCTC 11168;sub_species=jejuni;db_xref=taxon:192222
NC_002163.1 RefSeq misc_feature 19386 19445 . - . inference=protein motif:TMHMM:2.0;note=3 probable transmembrane helices predicted for Cj0012c Further possible text
NC_002163.1 RefSeq misc_feature 19482 19550 . - . inference=protein motif:TMHMM:2.0;note=3 probable transmembrane helices predicted for Cj0014c Sometimes there is more text
NC_002163.1 RefSeq misc_feature 22853 22921 . - . inference=protein motif:TMHMM:2.0;note=5 probable transmembrane helices predicted for Cj0017c
...
ご覧のとおり、最後の列にはいくつかの識別子(Cj0014c, Cj0017c, etc
)が含まれています。これらのIDの一部は他のファイルに保存されています。
ファイル2:
Cj0012c
Cj0027
CjNC9
Cjp01
SRP_RNA_Cjs03
CjNC11
CjNC1
Cj0113
Cjp03
Cj0197c
Cj0251c
awk(またはbash-script-tool)を使用してファイル1から次の行を削除するにはどうすればよいですか?サブストリング最後の列にファイル2で見つかったIDはありますか?たとえば、ファイル1の2行目は、ファイル2にCj0012c
あり、ファイル1のその行の最後の列にある文字列の一部であるため、削除されます。
私はこの問題で何時間も苦労しましたので、助けてくれてありがとう。 (できればコードの説明もお願いします!)
答え1
試してみるにはいくつかのオプションがあります。すべては、2番目のファイルで連想配列を構成し、最初のファイルの最後のフィールドに対してその要素をテストし、一致が見つかった場合に中断する方法に基づいています。
真の部分文字列の一致
awk -F'\t' 'NR==FNR{a[$1]; next} {for(i in a) {if(index($NF,i)>0) next}} 1' File2 File1
(たとえば)これはおよび/またはの部分文字列
Cj0012c
で識別されます。ABCj0012c
Cj0012cdef
上記と似ていますが、部分単語の一致を防ぐために、要素の両側を空白文字で埋めます。
awk -F'\t' 'NR==FNR{a[$1]; next} {for(i in a) {if(index($NF," "i" ")>0) next}} 1' File2 File1
a[" "$1" "]
(必要に応じて配列割り当て呼び出しに文字列を入力できます)(GNU awkが必要な場合があります)正規表現を使用して、束ねられた
File2
文字列で構成されるパターンを一致させます。単語境界アンカーgawk -F'\t' 'NR==FNR{a[$1]; next} {for(i in a) {if($NF ~ "\\<" i "\\>") next}} 1' File2 File1
このバージョンの潜在的な問題は、要素に
File2
正規表現メタ文字を含めることができることです。これらの文字は何らかの方法でエスケープする必要があります。
答え2
Perlに関するいくつかの知識:
perl -MList::Util=any -Mautodie -F'\t' -ane '
BEGIN { open $f, "<", shift @ARGV; chomp(@exclusions = <$f>); }
print unless any {$F[-1] =~ /\b\Q$_\E\b/} @exclusions;
' file2 file1
BEGIN行にはファイルの除外タグのリストが含まれています。
印刷ラインは、これらのラインに一致するラインをフィルタリングします。