繰り返しパターンがあるリストに基づいて、テキストファイルから複数行を抽出します。

繰り返しパターンがあるリストに基づいて、テキストファイルから複数行を抽出します。

各行が一意の識別子で始まるファイルがあります。たとえば、次のようになります。

$ cat source.txt
aaa text
bbb text
ccc text
ddd text
eee text

-fオプションと一緒にfgrepを使用して、別のファイル(「list.txt」と呼ばれる)にリストされている識別子を含む行を新しいファイルに保存してみました。

fgrep -f list.txt source.txt > new.txt

問題は、「list.txt」の一部の識別子が重複していることです。例:

$ cat list.txt
aaa
ccc
ccc
ccc
eee
eee

ここで grep は、繰り返される各識別子を一度だけリストされたように処理し、次のような結果を提供します。

$ cat new.txt
aaa text
ccc text
eee text

代わりに、繰り返し識別子を含む行をその識別子が繰り返される正確な回数でlist.fileに保存したいと思います。この場合、より良い最終結果は次のとおりです。

$ cat new.txt
aaa text
ccc text
ccc text
ccc text
eee text
eee text

grepが重複した識別子を一度だけリストされているように処理しないように強制する簡単な方法はありますか?または、awkを使用するなど、grepなしで目的の結果を得るための別の方法はありますか?


問題をよりよく視覚化するために、source.txtの実際の行は次のとおりです。

head -n 1 source.txt | cat -T
GCF_000005825.2_WP_003320558.1 MULTISPECIES: IS21-like element helper ATPase IstB [Bacillaceae]^IMNEQIQAYAKRLKLSWIRENFNQIEAETNEEYLLKLFEKEVQNREERKVNLLLSQAQLPKTGSTPFQWEHIQIPQGIERTAVINGDFIKERENLILYGGVGTGKTYLATLLSLNAIHRFGSQVKFYTVAGLVNKLIEANQKNTLPKLMKQIEKLDLLILDELGYIPLNKEGAELLFQVISMCYENRSIVITTNLQFGQWNHVFGDPILTEAVIDRLIHHSHLLVFKGDSFRYKESLLHQ

一致する識別子は次のとおりです。

GCF_000005825.2_WP_003320558.1

ベストアンサー1

これを行う1つの方法は次のとおりですawksource.txtメモリの問題が発生するほど大きくないと仮定します)。

$ awk 'NR==FNR{a[$1]=$0; next} $0 in a{print a[$0]}' source.txt list.txt
aaa text
ccc text
ccc text
ccc text
eee text
eee text
  • NR==FNR{a[$1]=$0; next}次に、最初のフィールドをキーにし、入力行全体を値として配列を作成します(source.txtこの場合は最初のファイルの場合)。
  • $0 in a{print a[$0]}list.txtファイルを処理するときは、各行が配列のキーとして存在することを確認し、その行をa印刷します。

以下は、メモリ側でより良いパフォーマンスを発揮する修正されたソリューションです(行にsource.txt単一のスペースで区切られた2つのフィールドがあると仮定)。

awk 'NR==FNR{a[$1]=$2; next} $0 in a{print $0, a[$0]}'

行全体ではなく、2番目のフィールドのみが配列に格納されます。印刷したら、キーの前に貼ります。

おすすめ記事