次のファイルがあります。
TITLE Protein in water t= 0.00000
REMARK THIS IS A SIMULATION BOX
ATOM 1 N SER A 107 20.799 63.728 25.985 1.00 0.00 N
ATOM 2 H1 SER A 107 21.658 64.259 25.980 1.00 0.00 H
これは非常に大きなファイルです:1.6G
2000万行が少し以上です。開始しない行を取得したいです。ATOM
そして終了しH
、別のファイルに保存します。これを行う最も効率的な方法は何ですか?
答え1
コメントの説明によると、
sed -n '/^ATOM.*H$/!p' input > output
「ATOM」で始まり、「H」で終わる行は名前付きファイルから削除(印刷されません)され、残りの行は名前付きファイルinput
に印刷されますoutput
。 sed 構文は左から右へ:
-n
- デフォルトでは行を印刷しない/^ATOM.*H$/
- ATOMで始まり、その後に任意の数の文字が続き、$
H()で終わる行を探します。!p
- 印刷ラインいいえ上記のパターンを合わせる
入力ファイルの例:
TITLE Protein in water t= 0.00000
REMARK THIS IS A SIMULATION BOX
ATOM 1 N SER A 107 20.799 63.728 25.985 1.00 0.00 N
ATOM 2 H1 SER A 107 21.658 64.259 25.980 1.00 0.00 H
TITLE Protein in water t= 0.00000H
REMARK THIS IS A SIMULATION BOXH
ATOM 1 N SER A 107 20.799 63.728 25.985 1.00 0.00 N
ATOM 2 H1 SER A 107 21.658 64.259 25.980 1.00 0.00 H
結果:
TITLE Protein in water t= 0.00000
REMARK THIS IS A SIMULATION BOX
ATOM 1 N SER A 107 20.799 63.728 25.985 1.00 0.00 N
TITLE Protein in water t= 0.00000H
REMARK THIS IS A SIMULATION BOXH
ATOM 1 N SER A 107 20.799 63.728 25.985 1.00 0.00 N
より直接的な sed 構文は次のとおりです。
sed '/^ATOM.*H$/d' input > output
これは次のように言います。
- (基本印刷ライン)
- ATOMで始まりHで終わる行を検索する
- この行を削除(印刷しない)
答え2
コンテンツに基づいて行を選択するツールは、grep、コンテンツ選択規則を次のように表現できる限り正規表現。
「次に始める」の正規表現はATOM
です^ATOM
。 「」で終わる正規表現はH
ですH$
。二つは重なり合うことができないので「で始まりATOM
、何でも含めて」で終わる正規H
表現はです^ATOM.*H$
。
正規表現と一致しない行を選択するには、オプションを使用します-v
。
grep -v '^ATOM.*H$' large_file.txt >not_atom_h.txt
より一般的な条件、特に列ベースの形式では、次のものを使用できます。アッ。以下は、サンプルデータと同じawkプログラムです。ATOM
最初の列がないか最後の列ではない行を印刷しますH
。この特別なケースでは、awkの利点はなく、速度が遅く単純ではありません。問題に若干のバリエーションがあるので言及します。たとえば、列にすることもできない場合もある列の後に列を追加すると、H
grepを使用して解決するのがより困難になります。
awk '$1 != "ATOM" || $NF != "H"' large_file.txt >not_atom_h.txt
答え3
コマンドラインの長さに関して私が考えることができる最も短い長さは次のとおりです。
grep -vx ATOM.\*H
処理速度に関して、少なくとも私のシステムで私が見つけた最も速い速度は次のとおりです。
mawk '!/^ATOM.*H$/'
答え4
(下記のコメントによると、これが最善の解決策ではありません)
次のようにすることもできます。
grep '[H$]' ソースファイル > ターゲットファイル
角かっこ内に「H$」(「Hで終わる」)を入れてこれを無効にします。したがって、grepは「H $」と一致しない項目を表示します。