外壳:在图案上方两行插入一个空白/新行

时间:2009-04-16 18:48:14

标签: python perl text sed awk

要在与正则表达式匹配的每一行上方添加一个空行,您可以使用:

sed '/regexp/{x;p;x;}'

但是我想添加一个空行,而不是上面的一个行,但两行行在与我的正则表达式相匹配的行之上。

我将匹配的模式是地址行中的邮政编码。

以下是文字格式的摘录:

  

随机信息(属于以前的业务)
  公司名称
  商家地址

例如:

  

语言:英语
  Arnold's Cove,Nfld(sub To Clarenville)
  Nile Road,Arnolds Cove,NL,A0B1N0

我想在商家名称上方添加一个新行:

  

语言:英语

     

Arnold's Cove,Nfld(sub To Clarenville)
  Nile Road,Arnolds Cove,NL,A0B1N0

6 个答案:

答案 0 :(得分:7)

更具可读性的Perl,并且可以很好地处理多个文件。

#!/usr/bin/env perl
use constant LINES => 2;
my @buffer = ();
while (<>) {
    /pattern/ and unshift @buffer, "\n";
    push @buffer, $_;
    print splice @buffer, 0, -LINES;
}
continue {
    if (eof(ARGV)) {
        print @buffer;
        @buffer = ();
    }
}

答案 1 :(得分:5)

有点像你在sed中的原始方法:

sed '/regexp/i\

$H
x'

基本思想是打印延迟一行的所有内容( x 更改保留和模式空间 - 隐式打印)。这需要完成,因为在我们检查下一行是否与正则表达式匹配之前,我们不知道是否 i 插入换行符。

($ H只有一个技巧可以打印最后一行。它将最后一行附加到保持缓冲区,以便最后的隐式打印命令也输出它。)

答案 2 :(得分:3)

简单:

sed '1{x;d};$H;/regexp/{x;s/^/\n/;b};x'

描述它

#!/bin/sed

# trick is juggling previous and current line in hold and pattern space

1 {         # at firs line
  x         # place first line to hold space
  d         # skip to end and avoid printing
}
$H          # append last line to hold space to force print
/regexp/ {  # regexp found (in current line - pattern space)
  x         # swap previous and current line between hold and pattern space
  s/^/\n/   # prepend line break before previous line
  b         # jump at end of script which cause print previous line
}
x           # if regexp does not match just swap previous and current line to print previous one

编辑:稍微简单的版本。

sed '$H;/regexp/{x;s/^/\n/;b};x;1d'

答案 3 :(得分:2)

perl -ne 'END{print @x} push@x,$_; if(@x>2){splice @x,1,0,"\n" if /[[:alpha:]]\d[[:alpha:]]\s?\d[[:alpha:]]\d/;print splice @x,0,-2}'

如果我把你的文件抓到这里,我得到你想要的东西......它很难看,但是你想要贝壳(即单线):-)如果我要完全用perl做这个,我会是能够清理它以使其接近可读性。 : - )

答案 4 :(得分:1)

这是一种适用于Python的方法。

import sys
def address_change( aFile ):
    address= []
    for line in aFile:
        if regex.match( line ):
            # end of the address
            print address[0]
            print 
            print address[1:]
            print line
            address= []
         else:
            address.append( line )
address_change( sys.stdin )

这允许您根据心脏内容重新格式化完整的地址。如果格式很复杂,可以展开此选项以创建定义Address类。

答案 5 :(得分:0)

我试过

sed '/regexp/a\\n'

但它插入了两个换行符。如果这不打扰你,请把它拿走。

  

echo -e“a \ nb \ nc”| sed'/ ^ a $ / a \ n'
  

     

b
  c

修改 既然你声明你需要在匹配的正则表达式上面插入两行,那么建议的正则表达式将不起作用。

我甚至不确定它是否适用于sed,因为你需要记住过去的行。对于像python或perl这样的高级语言来说,听起来像是一份工作: - )