используя sed в perl - PullRequest
       8

используя sed в perl

0 голосов
/ 06 июля 2010

У меня есть файл со следующими записями

--INFO----- Command processing: Name='shayam' Age='19' Project='Alwa'    
--ERROR---- Failed to process  
--INFO----- Command processing: Name='ram' Age='23' Project='Alwa'  
--INFO----- Command processing: Name='raja' Age='24' Project='Alwa'  
--INFO----- Command processing: Name='shyla' Age='27' Project='Alwa'  
--ERROR---- Failed to process

Мне нужно извлечь Имя и Возраст из соответствующей строки, для которой произошла ошибка. В этом случае мне нужно извлечь Name = shayam, Age = 19 и Name = shyla Age = 27.

Ответы [ 6 ]

2 голосов
/ 06 июля 2010

Это похоже на другие ответы здесь, только немного упрощено:

#!/bin/perl -w
use strict;
my ($name, $age);
while(<>) {
    ($name, $age) = ($1, $2) if /Name='?([\w]+)'?\s+Age='?([\d]+)'?/;
    print "$name, $age\n" if /^--ERROR--/;
}

Пример использования:

perl extract.pl input.log
2 голосов
/ 06 июля 2010

Я бы придерживался того же подхода, что и другой ответ на аналогичный вопрос, просто сохраняя последнюю найденную ИНФО

$p = "";
while(<>) {
    if ( /^--INFO/ ) { $p = $_; next; }
    next if !/^--ERROR/;
    $p =~ /Name='([^']+)'\s+Age='([^']+)'/;
    print $1, "  ", $2, "\n";
}
1 голос
/ 06 июля 2010

Я не уверен, понимаю ли я заголовок этого вопроса. Если вы программируете на Perl, вы можете использовать регулярное выражение для сбора информации следующим образом:

/Name='(.*?)' Age='(.*?)'/

Имя будет в $1, а возраст будет в $2.

1 голос
/ 06 июля 2010

Я бы начал с:

$ echo "--INFO----- Command processing: Name='shayam' Age='19' Project='Alwa'
--ERROR---- Failed to process
--INFO----- Command processing: Name='ram' Age='23' Project='Alwa'
--INFO----- Command processing: Name='raja' Age='24' Project='Alwa'
--INFO----- Command processing: Name='shyla' Age='27' Project='Alwa'
--ERROR---- Failed to process " | perl -ne '
    if (/^--INFO--/) {@line = split;}
    if (/^--ERROR--/) {print "$line[3] $line[4]\n";}'

, который производит:

Name='shayam' Age='19'
Name='shyla' Age='27'

Все, что он делает - это сохраняет информацию из каждой строки INFO, а затем распечатывает ее, когда вы получаете строку ERROR.

Вы заметите, что у него все еще есть кавычки вокруг значений, но, если вы действительно хотите избавиться от них, используйте (очень упрощенный) скрипт proc.pl:

#!/bin/perl -w
while (<STDIN>) {
    if (/^--INFO--/) {
        @line = split;
    }
    if (/^--ERROR--/) {
        $l3 = $line[3];
        $l4 = $line[4];
        $l3 =~ s/'//g;
        $l4 =~ s/'//g;
        print "$l3 $l4\n";
    }
}

Запуск этого с:

$ echo "--INFO----- Command processing: Name='shayam' Age='19' Project='Alwa'
--ERROR---- Failed to process
--INFO----- Command processing: Name='ram' Age='23' Project='Alwa'
--INFO----- Command processing: Name='raja' Age='24' Project='Alwa'
--INFO----- Command processing: Name='shyla' Age='27' Project='Alwa'
--ERROR---- Failed to process " | ./proc.pl

дает:

Name=shayam Age=19
Name=shyla Age=27

Вы можете использовать любой входной файл или поток с этим (например):

cat file.txt | ./proc.pl

или

./proc.pl <file.txt
0 голосов
/ 15 июля 2010

Оказывается, это один из редких случаев, когда redo полезен.

$ cat file.log
--INFO----- Command processing: Name='shayam' Age='19' Project='Alwa'    
--ERROR---- Failed to process  
--INFO----- Command processing: Name='ram' Age='23' Project='Alwa'  
--INFO----- Command processing: Name='raja' Age='24' Project='Alwa'  
--INFO----- Command processing: Name='shyla' Age='27' Project='Alwa'  
--ERROR---- Failed to process

$ perl -lne \
  '/^--INFO.+\b(Name=.+? Age=.+?'\'')/&&index($_=<>,"--ERROR")?redo:print$1' \
  file.log
Name='shayam' Age='19'
Name='shyla' Age='27'

Для INFO записей введите имя и возраст. Если следующая строка начинается с --ERROR, выведите на печать записанные параметры, но если нет, то проведите вперед, проверив, является ли следующая строка информационной записью.

0 голосов
/ 06 июля 2010

Попробуйте с:

sed -n "\$!N;/--ERROR----/{s/.*Name='\([^']*\)' Age='\([^']*\)'.*/Name=\1 Age=\2/p}" file

Если вы используете bash, возможно, вам придется отключить подстановку истории:

set +H
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...