【问题标题】:How to print certain lines from sections of a file separated by a blank line with sed如何使用 sed 从由空行分隔的文件部分打印某些行
【发布时间】:2019-10-25 20:22:46
【问题描述】:

我一直在尝试提出一个 sed 命令,该命令将从文件中由空行分隔的文本块中提取某些行。文本块如下。

# cat test_file.txt
line 1
line 2
line 3
line 4
line 5

line 1 
line 2
line 3
line 4
line 5

line 1 
line 2
line 3
line 4
line 5

我正在尝试从每个块中提取第 2 行和第 4 行,以便输出如下所示。

line 2
line 4

line 2
line 4

line 2 
line 4

我想出了一种方法来使用 sed 处理第一块文本:

# sed -n -e 2p -e 4p test_flie.txt
line 2
line 4

但一直无法找到一种方法让它继续处理每个文本块,直到文件末尾。任何指针将不胜感激。

【问题讨论】:

  • sed 用于对单个字符串进行简单替换,也就是说,对于任何其他文本操作,首先要考虑的工具是 awk。

标签: awk sed file-manipulation


【解决方案1】:

awks 段落模式专门用于处理您正在处理的以空行分隔的记录/文本块:

$ awk 'BEGIN{RS=""; ORS="\n\n"; FS=OFS="\n"} {print $2, $4}' file
line 2
line 4

line 2
line 4

line 2
line 4

参考the POSIX standard

如果 RS 为空,则记录由 <newline> 加上一个或多个空行组成的序列分隔,前导或尾随空行不应导致输入开头或结尾处的空记录

如果最终记录后不需要打印空行:

$ awk 'BEGIN{RS=""; FS=OFS="\n"} NR>1{print prev ORS} {prev=$2 OFS $4} END{print prev}' file
line 2
line 4

line 2
line 4

line 2
line 4

或者如果您出于某种原因不想使用段落模式,那么:

$ awk 'BEGIN{tgts[2]; tgts[4]} !NF{print ""; lineNr=0; next} ++lineNr in tgts' file
line 2
line 4

line 2
line 4

line 2
line 4

【讨论】:

  • 这样输出的末尾会有一个额外的空行,这就是为什么我避免使用null-RS
  • 根据我的经验,无论生成带有空行的输入文件,通常都会在每个块的末尾放置一个空行,而不仅仅是在块之间,即使它没有空行输出中每个块的结尾不会受到伤害,并且使进一步处理更容易,因为这样您就不需要将最后一个块与所有其他块区别对待,因此在每个块之后生成一个空行通常是一件好事,并且这很少是一件坏事。使代码更容易对每个块做任何你想做的事情。
  • @oguzismail 我更新了我的答案,以说明如果您不想在最终输出记录后出现空行,该怎么做。
【解决方案2】:

我会为此使用 awk,例如:

awk '(!NF&&m=NR)||NR-m==2||NR-m==4' file

【讨论】:

    【解决方案3】:

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

    sed -n '/\S/{n;p;n;n;p;:a;n;//ba;p}' file
    

    为显式打印设置-n 选项。打印第二行和第四行,然后丢弃所有非空白行并打印第一行空白。重复。

    【讨论】:

      猜你喜欢
      • 2011-09-26
      • 2011-01-29
      • 2017-02-05
      • 1970-01-01
      • 2011-03-28
      • 2014-04-28
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      相关资源
      最近更新 更多