在图案上方添加回车两行



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

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可以做到这一点吗?如果是,怎么办?

方法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 ~ /----*/

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

$perlscript.pl data.txt
tbl
---
tmp1
col1|col2
---------
22|  33
32|  45
tbl
---
tmp2
col1|col2| col3
---------------
22|  33|  123
32|  45|  456

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

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

在图案空间中读取两行,如果第二行以---结束,则在第一行上方插入一行。

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

这也可以写成:

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

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

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

最新更新