awk - 特定の列に他のテキストファイルの要素が部分文字列として含まれている場合、行を削除します。

awk - 特定の列に他のテキストファイルの要素が部分文字列として含まれている場合、行を削除します。

次の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番目のファイルで連想配列を構成し、最初のファイルの最後のフィールドに対してその要素をテストし、一致が見つかった場合に中断する方法に基づいています。

  1. 真の部分文字列の一致

    awk -F'\t' 'NR==FNR{a[$1]; next} {for(i in a) {if(index($NF,i)>0) next}} 1' File2 File1
    

    (たとえば)これはおよび/またはの部分文字列Cj0012cで識別されます。ABCj0012cCj0012cdef

  2. 上記と似ていますが、部分単語の一致を防ぐために、要素の両側を空白文字で埋めます。

    awk -F'\t' 'NR==FNR{a[$1]; next} {for(i in a) {if(index($NF," "i" ")>0) next}} 1' File2 File1
    

    a[" "$1" "](必要に応じて配列割り当て呼び出しに文字列を入力できます)

  3. (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行にはファイルの除外タグのリストが含まれています。
印刷ラインは、これらのラインに一致するラインをフィルタリングします。

関連情報