6

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

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

4

6 回答 6

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 = ();
    }
}
于 2009-04-16T20:55:45.863 回答
5

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

sed '/regexp/i\

$H
x'

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

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

于 2009-04-16T21:18:18.633 回答
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'
于 2009-04-17T10:41:04.727 回答
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 来执行此操作,我将能够清理使它变得可读性很多。:-)

于 2009-04-16T20:47:56.023 回答
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如果您的格式复杂,您可以扩展它以创建定义类。

于 2009-04-16T20:36:18.140 回答
0

我试过

sed '/regexp/a\\n'

但它插入了两个换行符。如果那不打扰您,请接受。

回声 -e "a\nb\nc" | sed '/^a$/a\n'
a

b
c

编辑: 既然您声明需要在匹配的正则表达式上方插入两行,则建议的正则表达式将不起作用。

我什至不确定它是否适用于 sed,因为您需要记住过去的行。听起来像是 python 或 perl 等高级语言的工作:-)

于 2009-04-16T18:55:30.647 回答