【问题标题】:sed Remove everything above last match foundsed 删除找到的最后一个匹配项之上的所有内容
【发布时间】:2015-03-31 03:38:56
【问题描述】:

我有一个文件:users.txt,如下所示:

    Name
    Jack
    Name
    Jackson
    Name
    Peter

我需要删除 ABOVE 找到的 last 匹配 Name 的所有内容,以便文件看起来像:

    Name
    Peter

我已经尝试在网上搜索,但只找到可以实现此目的的 awk 命令。 我需要将其 sed 以使用 -i 选项进行保存。我遇到过使用 awk 重定向 > 标准输出时文件有时为空的地方。

非常感谢您的时间和帮助。

【问题讨论】:

  • 您不需要使用 sed 来实现“就地”编辑 - 您可以使用 cmd file > tmp && mv tmp file 的标准技巧。
  • 是的,我试过了,但是当我重定向时,有时文件是空的。即使使用$ set +o noclobber 也不能解决文件有时为空的问题。
  • 这实际上对我有用......太棒了!谢谢 Tom Fenech。

标签: linux bash unix sed


【解决方案1】:

您可以将tacawk 一起使用两次:

tac file | awk '{print} /Name/{exit}' | tac
Name
Peter

【讨论】:

  • 非常聪明的方法。
  • awk '/Name/{exit}1'
  • @JID:那不会打印Name 行。
  • awk '1;/Name/{exit}'
  • 是的,通过将{print} 替换为1; 可以节省几个字符:P
【解决方案2】:

通过 sed,

tac file | sed -n '0,/Name/p' | tac

【讨论】:

  • 使用sed '/Name/q' 效率更高一些,因为您不必阅读您不关心的输入部分。
【解决方案3】:

使用sed 而不使用tac

sed -n '/Name/h; //!H; ${g;p}' file
  • 看到Name时,用当前行替换保持空间
  • Name 不可见时,追加当前行到保持空间
  • 在最后一行,将模式空间替换为保留空间并打印。

由于管道中没有sed,您可以使用-i 替换文件。

【讨论】:

  • 感谢@JID 的启发。
  • 我喜欢这个。不过,我会使用//!H 而不是/Name/!H// 再次尝试最近尝试的正则表达式)。
  • 谢谢,我为缺少DRY而烦恼。
【解决方案4】:

全部在 awk 中

awk 'x{x=x"\n"$0}/Name/{x=$0}END{print x}' file

【讨论】:

    【解决方案5】:

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

    sed 'H;/Name/h;$!d;x' file
    

    在保持空间中保持匹配,并在文件末尾打印最后一个匹配的保持空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 2020-03-03
      • 1970-01-01
      • 2020-07-06
      相关资源
      最近更新 更多