2012-05-14 1 views
3

У меня есть файл с и одну строку с в файле выглядеть следующим образомSplit LastName выходит на новую строку

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

Я просто хочу найти anylines, которые начинаются с GIVEN и найти последний символ пробела (при условии, что фамилия), затем создайте новую строку.

Так вход =

FOO=Bar 
GIVEN=David Smith 
Baz=123 

Выход должен быть

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

Это, насколько я мог бы получить:

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

Смотрите здесь демо http://regexr.com?30uh8

+0

Вы хотите сделать это в Perl? Awk? – Ansari

+0

+1 для ввода образца, ожидаемого выхода и некоторого кода. Удачи. – shellter

+0

Я рад за все, что работает на * inx – Daveo

ответ

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; 

Должен работать. Измените при необходимости, чтобы читать строки за строкой, если входной файл очень большой.

+0

Спасибо, что работает хорошо, я запускаю его по нескольким файлам вроде этого. 'найти. -type f -name \ *. txt | xargs perl -i -ple 's/^ (GIVEN \ =. +) \ s + (\ S +) $/$ 1 \ nLAST = $ 2 /' ' – Daveo

+0

Нет необходимости скрываться «=», потому что это не в «грязной дюжине»: \ |() [{^ $ * +? , – gangabass

+0

Зачем начинать чтение всего файла на одном и предлагать изменить его по очереди позже? Просто начните с этого пути. Это не сложнее и не вызывает проблем позже. –

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

Это не изменит исходную строку. – Vijay

+0

true. Обновлено .. –

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 
+0

не все имена в примере ввода имеют всего 2 слова. –

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=/' ... 

Это, однако, может привести к искажению имен некоторых людей. Не каждая фамилия - это одно слово. Спросить человека - единственный хороший способ узнать, что такое их фамилия.