【问题标题】:I want to print the last line of group using sed我想使用 sed 打印组的最后一行
【发布时间】:2019-10-15 06:50:30
【问题描述】:

我有如下所示的文件

Section1
    George, 1998-1995
     Peter, 1999-1990
     Simon, 1988-1960
Section2
     Gery,  2019-2015
     John,  1984-1983
     Thomson,  1978-1965

当我给出 Section1 时,预期的输出是 西蒙,1988-1960

像这样我有很多部分。我想通过不使用 awk 的 sed 来实现这一点。

我试过这样。但它具有行号硬编码。而且它正在打印完整的范围

sed -n '/Section1/,4{p}'

在这里我可以删除硬编码。但无法打印最后一行。而且下一节的名字也来了。

sed -n '/Section1/ , /Section./{p}'

【问题讨论】:

  • 这些部分是否总是有 3 行缩进文本?你是GNU sed 吗?
  • 不,不是那样的。举个例子,我把它当作 3 行。我正在使用 Arch linux。
  • 能否请您查看sed 的答案,让您知道是否有任何适合您的方法?

标签: sed


【解决方案1】:

gnu awk 解决方案。

awk -v RS='Section' '$1=="1" {print $(NF-1),$NF}' file
Simon, 1988-1960

通过将记录选择器设置为Section,awk 在块中工作。然后打印块匹配1的第二个最新和最新的字段,因为Section被剥离了。

【讨论】:

  • 感谢您的回复。我正在为此寻找 sed 解决方案。能不能给个sed解决方案。
  • 你没有awk? sed 可能不是所有人的完美解决方案。 sed 更多的是逐行定位。 awk 比 sed 能做的更多
  • Jotne 是的,我有,我的数据比示例中的数据复杂一点,我屏蔽了数据并在这里举了一个例子。在采用该行之后,我已经编写了一个 sed 代码来再次解析该行。并使用 sed 完成整个处理。我不想只为此而使用 awk。
  • 我可以使用 sed 获取范围。但无法获得倒数第二行...
  • 那么,如果你全部发布,我们可以做出更好的解决方案,只使用一个命令,而不是混合使用。
【解决方案2】:

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

sed '$b;N;/\nSection/P;D' file

制作一个包含两行的移动窗口,如果第二行以Section 开头并且始终是最后一行,则打印第一行。

对于特定部分的最后一行,请使用:

sed -n '/^Section1/{:a;h;$!{n;/^\S/!ba};x;s/^\s*//p}' file

【讨论】:

  • 此代码没有执行所需的操作。它提取所有块的最后一行,而不进行修剪。当传递特定的Section 时,OP 需要获取块的最后一行。
  • 能否请您告诉我为什么我的答案被否决?它正在工作并且解释清楚......还是我错过了任何重要的事情?
  • @WiktorStribiżew 很抱歉你被否决了,但不是我。您的答案的粗略视图本质上与我的第二个解决方案相同,但是没有必要使用范围并且它不满足文件边缘情况的结尾,即如果指定的部分是 Section2 会发生什么?跨度>
  • 感谢您的反馈和支持。即使没有第 2 节,该范围也能正常工作,因为当它丢失时,它会读取到文件末尾。
【解决方案3】:

你可以考虑使用

sed -n '/^Section1$/,/^Section[0-9]*$/{:a;h;n;/^Section[0-9]*$/!ba;x;s/^[ \t]*//;p}' file > newfile

见the online demo。

详情

  • -n - 开关抑制默认线路输出模式
  • /^Section1$/,/^Section[0-9]*$/ - 等于Section1 的行和完全匹配Section 和任何0 或多个数字模式的行之间的一行行(下一个{...} 命令组与匹配的范围有关这个)
  • :a - 设置一个名为 a 的标签
  • h - 将当前行复制到保持缓冲区中
  • n - 丢弃当前模式空间值并将下一行读入其中
  • /^Section[0-9]*$/!ba - 如果模式空间值与结束块行不匹配,则返回标签 a
  • x - 否则,一旦我们到达最后一行,前一行就在保持空间中,所以x 用于交换保持空间和模式空间
  • s/^[ \t]*// - 删除初始空格
  • p - 打印模式空间。

【讨论】:

    【解决方案4】:

    正则表达式:

    (Section1)((\n.*,.*)*\n\s*)(?'lastLine'.*)
    

    测试here。

    我不明白你想对结果做什么,所以我不能告诉你确切的sed 命令。

    【讨论】:

    • 我放的例子是一个样本数据。最后,我对每个部分的数据进行了总结。我只想选择摘要。这就是用例。你能帮我解决 sed 吗
    • regex101 不适合命令行工具,因为 sed 仅支持 BRE/ERE 风格的正则表达式,没有环视、非贪婪等功能
    • @Vipin:“摘要”是一回事,“最后一行”是另一回事。我提供了一个正则表达式,它提取了一个部分的最后一行,即使它在sed 中可能不起作用,如一条评论中所述。在创建命令行之前,我们需要正确理解需求。 sed 通常用于替换。你想换什么?为什么不能使用其他工具?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 1970-01-01
    • 2023-03-28
    • 2021-11-29
    • 1970-01-01
    • 2012-01-09
    • 1970-01-01
    相关资源
    最近更新 更多