将姓氏拆分为新行

时间:2012-05-14 03:49:17

标签: regex perl unix awk

我有文件和文件中的一行看起来像这样

GIVEN=David Smith
GIVEN=John Doe Young
GIVEN=Ms Sam Parker
GIVEN=Mr James Free Foo ABC
GIVEN=Joe Cam-Barr

我只是想找到以GIVEN开头的任意行,找到最后一个空格字符(假设这是姓),然后再换一行。

所以输入=

FOO=Bar
GIVEN=David Smith
Baz=123

输出应为

FOO=Bar
GIVEN=David
LAST=Smith
Baz=123

这是我能得到的:

(?<=(GIVEN=))(.*\ )

请参阅此处了解演示http://regexr.com?30uh8

4 个答案:

答案 0 :(得分:1)

open(my $IN, "<infile.txt") or die $!;
chomp(my @lines = <$IN>);
close $IN;

foreach(@lines){
  s/^(GIVEN\=.+)\s+(\S+)$/$1\nLAST=$2/;
}

open(my $OUT,">outfile.txt") or die $!;
print "$_\n" foreach(@lines);
close $OUT;

应该有效。如果输入文件非常大,则根据需要进行修改以逐行读取。

答案 1 :(得分:1)

awk ' /^GIVEN=/ {last=$NF; $NF=""; print; print "LAST=" last; next} 1' filename

答案 2 :(得分:1)

substrrindex运算符专为此任务而设计。 rindex找到从字符串右侧开始的第一次出现的字符的位置,substr采用位置和长度来插入子字符串:

substr适用于$_,从rindex给出的位置开始,用1替换下一个\nLAST=字符:

while( <> ) {
    substr( $_, rindex( $_, ' ' ), 1, "\nLAST=" ) if /\AGIVEN=/;
    print;
    }

当你查看这段代码时,你会发现它已经是你所需要的单行代码,尽管在这种情况下,我使用通用引用来避免shell插值问题:

% perl -pi.old -e 'substr($_,rindex($_,q( )),1,qq(\nLAST=)) if /\AGIVEN=/' ...
但是,这可能会破坏一些人的名字。不是每个姓氏都是一个单词。询问这个人是了解他们姓氏的唯一好方法。

答案 3 :(得分:0)

thames.434> cat file
    FOO=Bar
    GIVEN=David Smith
    Baz=123

thames.435> awk '{if ($0~/GIVEN/){x=$2;$2="";print;print "LAST=",x}else print}' file
    FOO=Bar
GIVEN=David 
LAST= Smith
    Baz=123