大容量ファイルから「H」で終わらない行を別のファイルに抽出する

大容量ファイルから「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
ATOM      2  H1  SER A 107      21.658  64.259  25.980  1.00  0.00           H

これは非常に大きなファイルです:1.6G2000万行が少し以上です。開始しない行を取得したいです。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の利点はなく、速度が遅く単純ではありません。問題に若干のバリエーションがあるので言及します。たとえば、列にすることもできない場合もある列の後に列を追加すると、Hgrepを使用して解決するのがより困難になります。

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 $」と一致しない項目を表示します。

関連情報