【问题标题】:Remove line break every nth line using sed使用 sed 删除每第 n 行的换行符
【发布时间】:2015-08-19 12:04:26
【问题描述】:

示例:有没有办法使用 sed 删除/替换文件中每 3n + 1 和 3n+ 2 行的模式?

比如转

Line 1n/
Line 2n/
Line 3n/
Line 4n/
Line 5n/
Line 6n/
Line 7n/
...

Line 1 Line 2 Line 3n/
Line 4 Line 5 Line 6n/
...

我知道这可能可以由 awk 处理。但是sed呢?

【问题讨论】:

  • n/ 是字面意思还是“换行符”的尝试?
  • em...我可以想到一种方法来实现您的具体示例。但最好弄清楚你到底想达到什么目标。
  • GNU sed 有一种方法可以直接指定你想要什么,但我不只使用 GNU sed,所以我没有花时间学习它。就像1~3 匹配第一行和之后的每三行。有关详细信息,请参阅 GNU sed 手册中的 addresses
  • 其实标题应该是Remove all line breaks except every nth [...]

标签: linux bash sed


【解决方案1】:

好吧,我只使用awk 来解决这个问题1,因为它有点复杂,但是,如果您真的打算使用sed,以下命令将组合三行合并成一行(根据标题和文本,这似乎是您所追求的,尽管 /n 奇怪地用于换行):

sed '$!N;$!N;s/\n/ /g'

查看以下成绩单了解如何测试:

$ printf 'Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n' | sed '$!N;$!N;s/\n/ /g'
Line 1 Line 2 Line 3
Line 4 Line 5

子命令如下:

  • $!N 会将下一行附加到模式空间,但前提是您不在最后一行(您这样做两次以获得三行)。模式空间中的每一行都由换行符分隔。
  • s/\n/ /g 用空格字符替换模式空间中的所有换行符,有效地将三行合二为一。

1 类似:

awk '{if(NR%3==1){s="";if(NR>1){print ""}};printf s"%s", $0;s=" "}'

这很复杂,因为您可能不希望每行末尾有多余的空格,因此需要引入 s 变量。

由于sed 变体更小(一旦你理解了它就不那么复杂了),你最好还是坚持下去。好吧,至少直到你想要组合 17 行的组,或者做一些比sed 要处理的更复杂的事情:-)

【讨论】:

    【解决方案2】:

    该示例用于合并 3 个连续的行,尽管描述不同。要生成示例输出,您可以使用awk idiom

      awk 'ORS=NR%3?FS:RS' <(seq 1 9)  
      1 2 3
      4 5 6
      7 8 9
    

    在您的情况下,需要预先定义记录分隔符以包含文字

    awk -v RS="n/\\n" 'ORS=NR%3?FS:RS'
    

    【讨论】:

    • 需要在末尾打印一个换行符,带有END {printf "\n"}
    【解决方案3】:

    好的。以下是通常使用 awk 和 sed 处理它的方法。

    awk:

    awk 'NR % 3 { sub(/pattern/, substitution) } { print }' file | paste -d' ' - - -
    

    sed:

    sed '{s/pattern/substitution/p; n;s/pattern/substitution/p; n;p}' file | paste -d' ' - - -
    

    它们都将3n+13n+2 行中的模式替换为substitution 并保持3n 行不变。

    paste - - - 是将标准输出折叠 3 的 bash 习惯用法。

    【讨论】:

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