sed:根据第二行连接行

问题描述 投票:0回答:6

我有一个文件,偶尔会有分割线。该行以“+”开头(前面可能有空格)来表示分割。

line 1
line 2
  + continue 2
line 3
...

我想加入分割线:

line 1
line 2 continue 2
line 3
...

使用 sed。我不清楚如何将一行与前面加入一行。

有什么建议吗?

sed
6个回答
28
投票

这可能对你有用:

sed 'N;s/\n\s*+//;P;D' file

这实际上是四个命令:

  • N

    将输入文件中的行追加到模式空间
  • s/\n\s*+//

    删除换行符,后面的空格和加号
  • P

    从模式空间打印行直到第一个换行符
  • D

    从模式空间中删除行直到第一个换行符,例如刚刚打印的部分

相关手册页部分是

要添加 1 条或多条

+
行,请使用:

sed ':a;N;s/\n\s*+//;ta;P;D' file

4
投票

在 sed 中执行此操作当然是一个很好的练习,但在 Perl 中则非常简单:

perl -0777 -pe 's/\n\s*\+//g' input

4
投票

POSIX sed 对保留空间的不同使用...在合并行之前将整个文件加载到保留空间中。

sed -n '1x;1!H;${g;s/\n\s*+//g;p}'

  • 1x
    在第一行,将该行交换到空的保留空间
  • 1!H
    在非第一行,追加到保留空间
  • 最后一行
  • $
    • g
      获取保留空间(整个文件)
    • s/\n\s*+//g
      替换前面的换行符
      +
    • p
      打印所有内容

输入:

line 1
line 2
  + continue 2
  + continue 2 even more
line 3
+ continued

成为

line 1
line 2 continue 2 continue 2 even more
line 3 continued

这个(或potong的答案)可能比

sed -z
实现更有趣,如果需要其他命令来对数据进行其他操作,您可以简单地将它们粘贴在
1!H
之前,而
sed -z
会立即将整个文件加载到模式空间。这意味着您在任何时候都不会操纵单行。
perl -0777
也一样。

换句话说,如果您还想删除以

*
开头的注释行,请添加
/^\s*\*/d
来删除该行

sed -n '1x;
/^\s*\*/d;
1!H;${g;s/\n\s*+//g;p}'

对:

sed -z 's/\n\s*+//g;
s/\n\s*\*[^\n]*\n/\n/g'

前者在保留空间中逐行的积累使您处于经典的 sed 行处理状态,而后者的

sed -z
将您转入可能是一些痛苦的子字符串正则表达式。

但这只是一种边缘情况,你总是可以将

sed -z
通过管道传回到 sed 中。所以+1。

互联网搜索脚注:这是 SPICE 网表语法。


3
投票

我不偏爱 sed,所以这对我来说是一个很好的挑战。

sed -n '1{h;n};/^ *+ */{s// /;H;n};{x;s/\n//g;p};${x;p}'

在 awk 中,这大约是:

awk '
    NR == 1 {hold = $0; next}
    /^ *\+/ {$1 = ""; hold=hold $0; next}
    {print hold; hold = $0}
    END {if (hold) print hold}
'

如果最后一行是“+”行,则 sed 版本将打印尾随空白行。不知道如何抑制它。


3
投票

您可以在 Ex 模式下使用 Vim:

ex -sc g/+/-j -cx file
  1. g
    全局搜索

  2. -
    选择上一行

  3. j
    与下一行连接

  4. x
    保存并关闭


2
投票

针对

sed
版本的解决方案,可以读取 NUL 分隔的数据,就像这里 GNU Sed 的
-z
:

sed -z 's/\n\s*+//g'

与 potong 的解决方案相比,它的优点是能够连接以

+
开头的多条线。例如:

line 1
line 2
  + continue 2
  + continue 2 even more
line 3

成为

line 1
line 2 continue 2 continue 2 even more
line 3
© www.soinside.com 2019 - 2024. All rights reserved.