在模式上方添加回车符两行

时间:2018-11-02 15:42:16

标签: sed

我有一个看起来像这样的数据库日志文件

tbl
---
tmp1
col1|col2
---------
  22|  33
  32|  45
tbl
---
tmp2
col1|col2| col3
---------------
  22|  33|  123
  32|  45|  456

我正在尝试编写sed命令,以查找以开头的行 与'---'并在上面两行添加回车符。所以这样 输出如下:

tbl
---
tmp1

col1|col2
---------
  22|  33
  32|  45

tbl
---
tmp2

col1|col2| col3
---------------
  22|  33|  123
  32|  45|  456

是否可以使用sed执行此操作?如果可以,怎么办?

2 个答案:

答案 0 :(得分:1)

方法1

按照Sundeep的建议,使用tac反转输入使此问题变得更加容易:

tac data.txt | sed '/^----*$/ {N;a\

}' | tac | sed '2,$p'

方法2

这是一个很难解决的仅针对sed的问题(至少对我而言)。我很近,但是选择了perl。 sed即将完成,因此可以肯定地进行翻译。凭直觉,我想这可以通过增加一个行缓冲来完成,我希望有人用仅sed的实现来回答。有时它根本不成立。有太多奇怪的案例,我选择对整个过程进行排队:

my @queue = ();

while (<>) {
    if (/----*/) {
        do {
            print $queue[0];
            print "\n" if scalar @queue == 2;
            shift @queue;
        } while (scalar @queue);
        print;
    } else {
        push @queue, $_;
    }
}
do print shift @queue while scalar @queue;

我开始研究类似的问题:

1
0
2
1
0

数字表示与以下---*行的偏移量,其中0----*行。偏移量为2时,打印新行。

问题陈述明确表示为:
print \n before previous line if line ~ /----*/

无论如何,这是调用/的输出:

$ perl script.pl data.txt
tbl
---
tmp1

col1|col2
---------
  22|  33
  32|  45

tbl
---
tmp2

col1|col2| col3
---------------
  22|  33|  123
  32|  45|  456

答案 1 :(得分:0)

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

sed -e 'N;/---\s*$/{2!i\\' -e '};P;D' file

将两行读入模式空间,如果第二行以---结尾,则在第一行上方插入一行。

通常,这会在文件的开头插入一个空行,但是通过检查第二行是否为文件的第二行,可以避免这种情况。

这也可以写成:

sed 'N;/---\s*$/!P;//!D;2!i\\' file

最后一种解决方案的替代方法是:

sed 'N;/---[[:space:][:cntrl:]]*$/!P;//!D;2!i\\' file