从大文件中提取不以“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.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。 “以”结尾的正则表达式HH$。由于两者不能重叠,因此“以 开头ATOM,然后包含任何内容,以 结尾H”的正则表达式为^ATOM.*H$

要选择与正则表达式不匹配的行,请使用 选项-v

grep -v '^ATOM.*H$' large_file.txt >not_atom_h.txt

对于更一般的条件,尤其是基于列的格式,您可以使用awk。这是一个与示例数据等效的 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$”不匹配的条目

相关内容