我有文件和文件中的一行看起来像这样
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
答案 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)
substr和rindex运算符专为此任务而设计。 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