2 つのファイルを 1 行ずつ比較して、ファイル 1 のパターンがファイル 2 で (全体または一部) 見つからない場合は、ファイル 1 の行を印刷します。

2 つのファイルを 1 行ずつ比較して、ファイル 1 のパターンがファイル 2 で (全体または一部) 見つからない場合は、ファイル 1 の行を印刷します。

2つのファイルがあります。

ファイル1(検索):

1  
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT  
2  
GACGGAGGATGCAAGTGTTATCCGGAAT  
3  
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC  
4  
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG 

ファイル2(モード):

GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCG
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCCGTAG 

私に必要なのは:

1  
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT  
2  
3  
4  
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG  

つまり、パターンファイルから検索ラインを検索するスクリプトが必要であり、検索ラインを完全にまたは部分的に見つけることができる場合(「2」以降の行の場合)、その検索ラインを作成しないでください。する必要があります。 1.

私はこのフォーラムで見つけた多くのgrepとawkスクリプトを試しましたが、私の要件を満たすスクリプトはありません。

awk 'FN==NR {exclude[$0];next} !($0 in exclude)' file2 file1  

または

awk 'NR==FNR{a[$1]++;next} !($1 in a) {print $1} {next}' file2 file1

私もgrepを試しました。

とにかく、私が試したすべてのスクリプトは、部分一致ではなくパターンと正確に一致するものを見つけました。

誰でもどんなアイデアがありますか?

答え1

awkスクリプトの使用:

NR == FNR       { seq[++n] = $1; next }

{
    header = $0
    getline

    for (i = 1; i <= n; ++i) {
        if (match(seq[i], $0) > 0) {
            print header
            next
        }
    }

    print header
    print
}

実行してください:

$ awk -f script.awk file2 file1
1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG

スクリプトは最初にfile2配列から2000個のシーケンスを読み取り、次に配列からseqヘッダーを読み取り(次に使用)file1からシーケンスを読み取ります。次に配列を繰り返して、現在のシーケンスを含むシーケンスを見つけます。そのようなシーケンスが見つかると、ヘッダーが印刷され、スクリプトは実行中の次の行に続きます。それ以外の場合は、タイトルと順序が印刷されます。file1getlineseqfile1file1

スクリプトにはfile1ヘッダーとシーケンス行が交互に含まれていると見なされ、複数行のシーケンスは含まれません。

以下は同じスクリプトですが、DRY原則(「繰り返さないでください」)を使用してください。

NR == FNR       { seq[++n] = $1; next }

{
    header = $0
    getline

    found = 0
    for (i = 1; i <= n; ++i) {
        if (match(seq[i], $0) > 0) {
            found = 1
            break
        }
    }

    print header
    if (!found) print
}

答え2

awk+grep解決策:

awk '/^[^>0-9]/{ 
         m = ""; cmd = sprintf("grep -m1 %s file2", $0);
         cmd | getline m; close(cmd);
         if (m) next; 
     }1' file1
  • cmd- 主なgrepコマンド
  • m- 可能な一致項目で埋められた変数

出力:

1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG

答え3

grep -vxf <(grep -of file_1 file_2 | sort -u) file_1

ファイル1

1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
GACGGAGGATGCAAGTGTTATCCGGAAT
3
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG

ファイル_2

GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCG
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCC
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGCGTCCGTAG

出力

1
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCGTAAAGTTTTTTTTT
2
3
4
GACGGAGGATGCAAGTGTTATCCGGAATCACTGGGCCGTCCGTAG

関連情報