リストの文字列が行の最初の12文字以内で見つかった場合は、大容量ファイルから行を削除しますか?

リストの文字列が行の最初の12文字以内で見つかった場合は、大容量ファイルから行を削除しますか?

以下のように、+184000行* +5400行を含むファイル行列があります。

denovo1 someverylaaargenumbers and lotandlotsoftextuntil 5400.........
denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo100 someverylaaargenumbers and lotandlotsoftextuntil 5400.......
denovo1000 someverylaaargenumbers and lotandlotsoftextuntil 5400......
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo100000 someverylaaargenumbers and lotandlotsoftextuntil 5400......
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

2番目のファイルには、次の識別子のリストがあります。

denovo1
denovo100
denovo1000
denovo100000

識別子がファイル2で見つかった場合は、行列1の行を消去したいと思います。したがって:

denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

1行ずつ読み、ファイル2の文字列を見つけるための短いUnixコードがあります。

while read -r line
do
echo $line
sed -i '' '/$line/d' /my/path/matrix1
done < /my/path/file2

動作はされますが、すべての行を最後まで読んでくれるので時間がかかります。マシンに各行の最初の12文字だけを読み取る方法はありますか?

答え1

そしてgrep

grep -vwf file matrix > matrix.new
mv matrix.new matrix
  • パターン入力ファイル-f FILEとして使用するオプションFILE
  • -w単語全体を構成する一致を含む行のみを選択するオプション
  • -v一致しない行を選択するオプション

空行はfile許可されません。

あるいは、識別子ファイルを手動で生成する場合は、アンカーを使用して行の^先頭を一致させ、各識別子の後にスペース文字を追加してパターンの終わりを表示します。

printf '^%s \n' denovo{1,100,1000,100000} > file
grep -vf file matrix > matrix.new
mv matrix.new matrix

答え2

努力する:

$ awk 'FNR==NR{ids[$1]; next} !($1 in ids)' ids file
denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

仕組み:

  • FNR==NR{ids[$1]; next}

    最初のファイルを読み込むと、idを持つids連想配列にキーが生成されます。idsその後、残りのコマンドをスキップしてその行にnext移動します。

  • !($1 in ids)

    2番目のファイルを読み取るときに最初のフィールドが連想配列のキーではない場合、その行は印刷されますids

ソースファイルの更新

コードが正しく動作すると思われる場合は、ファイルを変更できます。

awk 'FNR==NR{ids[$1]; next} !($1 in ids)' ids file >tmp && mv tmp file

関連情報