3

私はファイルを持っています、そしてファイルの1行はこのように見えます

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

4 に答える 4

1

substrおよびrindex演算子は、このタスク用に特別に設計されています。rindexは、文字列の右側から始まる文字の最初の出現位置を検出し、substr、部分文字列を挿入するための位置と長さを取ります。

このsubstrはで機能し$_、で指定された位置から開始し、次の文字を:rindexで置き換えます。1\nLAST=

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

このコードを見ると、すでにワンライナーに必要な形式になっていることがわかりますが、その場合は、シェル補間の問題を回避するために一般化された引用符を使用します。

% perl -pi.old -e 'substr($_,rindex($_,q( )),1,qq(\nLAST=)) if /\AGIVEN=/' ...

しかし、これは一部の人々の名前を混乱させる可能性があります。すべての名前が1つの単語であるとは限りません。その人に尋ねることは、彼らの名前が何であるかを知る唯一の良い方法です。

于 2012-05-14T19:50:43.340 に答える
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;

動作するはずです。入力ファイルが非常に大きい場合は、必要に応じて行単位で読み取るように変更します。

于 2012-05-14T03:57:50.670 に答える
1
awk ' /^GIVEN=/ {last=$NF; $NF=""; print; print "LAST=" last; next} 1' filename
于 2012-05-14T10:29:29.990 に答える
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
于 2012-05-14T11:18:52.923 に答える