
以下のように、+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