【问题标题】:removing unmatched lines with SED使用 SED 删除不匹配的行
【发布时间】:2015-09-22 00:51:12
【问题描述】:

我正在尝试删除除具有特定匹配模式的 3 行单独的行之外的所有内容,只留下我想要的 3 行

这是我的代码;

sed -n '/matching pattern/matching pattern/matching pattern/p' > file.txt

【问题讨论】:

  • 这几乎是正确的。但是/pattern/pattern/pattern/ 作为陈述没有意义。你想要/pattern/p; /pattern/p; /pattern/p
  • grep 非常直观。通常 sed 更适合需要文本编辑的内容。
  • 发布一些可测试的样本输入和预期输出。

标签: regex linux bash awk sed


【解决方案1】:

如果同一行有多个命令,则需要用;分隔命令:

sed -n '/matching pattern/p;/matching pattern2/p;/matching pattern3/p' file

或者,您可以将它们放在单独的行中:

sed -n '/matching pattern/p
        /matching pattern2/p
        /matching pattern3/p' file

除此之外,您还可以使用正则表达式替换:

sed -rn '/(pattern|pattern2|pattern3)/p' file

或(更好)使用grep

grep -E '(pattern|pattern2|pattern3)' file

但是,如果模式变得更长和更复杂,这可能会变得混乱。

【讨论】:

  • 我建议使用-e 选项使独立表达更加明确。
  • 好点。我也考虑过,但不想添加更多替代方案。也可以使用awk。 :)
【解决方案2】:

求救!

awk '/pattern1/ || /pattern2/ || /pattern3/' filename

我认为它比替代品更清洁。

【讨论】:

  • Plus 1. 我也喜欢 awk 可以同时搜索各种模式。我什至越来越习惯于一直使用awk 而不是 grep,即使只有一种搜索模式 -> 只是为了以后我想添加一些东西。但是,我仍然会说grep 是在文件中搜索模式的最干净 方式。相信我,有很多人不理解上述awk cmd。悲伤但真实。但是,如果使用grep,至少每个人都知道该命令是关于在文件中搜索的。
  • + grep 支持很多有用的选项,例如-i-w-F
  • @hek2mgl 我认为正是缺少魔法选项让 awk 更干净。 .
【解决方案3】:

Sed 删除

做这种事情的方法总是不止一种,但一种有用的 sed 编程模式是使用交替删除。例如:

# BSD sed
sed -E '/root|daemon|nobody/!d' /etc/passwd

# GNU sed
sed -r '/root|daemon|nobody/!d' /etc/passwd

这使得表达诸如“删除所有除了列出的条款”之类的想法成为可能。即使表达式在功能上是等效的,使用与您试图传达的想法最接近的结构也会很有帮助。

【讨论】:

  • 值得知道 | 在正则表达式(即管道)内匹配自身,除非设置了 -E (-r GNU sed),而当这些选项中的任何一个被设置或前面\ \| 当它成为表示交替的元字符时。
【解决方案4】:

这可能对你有用(GNU sed):

sed '/pattern1/b;/pattern2/b;/pattern3/b;d' file

sed 的正常流程是打印处理后留在模式空间中的内容。因此,如果所需的模式在模式空间中,让 sed 做它的事情,否则删除该行。

注意b 命令类似于 goto,如果它没有后续标识符,则意味着中断任何进一步的 sed 命令并打印(或者如果 -n 选项正在运行,则不打印)模式空间的内容.

【讨论】:

  • 感谢您的帮助!
【解决方案5】:

如果我理解正确的话:

sed -n '/\(pattern1\|pattern2\|pattern3\)/p' file > newfile

【讨论】: