2015-06-10 2 views
0

У меня есть файл со следующим содержанием:Использование Grep для извлечения значения из файла

<rdf:RDF 
    xmlns:rdf="/www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="/xmlns.com/foaf/0.1/" 
    xmlns:jfs="//abc.net/xmlns/prod/xyz/jfs/1.0/"> 
    <rdf:Description rdf:about="//alm.com/abc/users/piku"> 
    <foaf:mbox rdf:resource="mailto:[email protected]"/> 
    <foaf:nick>piku</foaf:nick> 
    <foaf:name>Pallavi Mishra</foaf:name> 
    <jfs:archived rdf:datatype="//www.w3.org/2001/XMLSchema#boolean" 
    >false</jfs:archived> 
    <rdf:type rdf:resource="//xmlns.com/foaf/0.1/Person"/> 
    </rdf:Description> 
</rdf:RDF> 

Культиватор можно извлечь электронный идентификатор «[email protected]» и имя «Pallavi Mishra» из этого файла используя perl или grep.

Мой кусок кода:

my $Name = `cat abc.json | perl -l -ne '/<j.0:name>(.*)<\\/j.0:name>/ and print \$1'`; 
my $EmailAddress = `cat abc.json | grep mailto | awk 'BEGIN{FS="\\"|:"} {for(i=1;i<NF;i++) if(\$i ~ /@/) print \$i}'`; 
+2

Попробуйте использовать синтаксический анализатор XML, такой как xmllint или xmlstarlet. – Cyrus

+0

Почему ваши данные XML в файле с именем 'abc.json'? Это код оболочки или код Perl? Прими решение! –

+0

Я хочу извлечь эти два значения из файла abc.json в perl-скрипте. – user3616128

ответ

3

Вы должны использовать правильный XML-парсер, такие как XML::LibXML

Эта короткая программа демонстрирует идею

use strict; 
use warnings; 
use 5.014; # For non-destructive substitution 

use XML::LibXML; 

my $doc = XML::LibXML->load_xml(IO => \*DATA); 

my $desc = $doc->find('/rdf:RDF/rdf:Description')->get_node(1); 
my $mbox = $desc->find('foaf:mbox/@rdf:resource')->string_value =~ s/^mailto://ir; 
my $name = $desc->find('foaf:name')->string_value; 
print qq{"$name" <$mbox>\n}; 

__DATA__ 
<rdf:RDF 
    xmlns:rdf="/www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:foaf="/xmlns.com/foaf/0.1/" 
    xmlns:jfs="//abc.net/xmlns/prod/xyz/jfs/1.0/"> 
    <rdf:Description rdf:about="//alm.com/abc/users/piku"> 
    <foaf:mbox rdf:resource="mailto:[email protected]"/> 
    <foaf:nick>piku</foaf:nick> 
    <foaf:name>Pallavi Mishra</foaf:name> 
    <jfs:archived rdf:datatype="//www.w3.org/2001/XMLSchema#boolean" 
    >false</jfs:archived> 
    <rdf:type rdf:resource="//xmlns.com/foaf/0.1/Person"/> 
    </rdf:Description> 
</rdf:RDF> 

выход

"Pallavi Mishra" <[email protected]> 
1

Do не попытайтесь разобрать XML, используя собственную обработку строк в Perl. Это неприятный ненадежный хак.

Perl - это многоязычный способ. Вам не нужно использовать оболочку, чтобы помочь Perl анализировать XML.

use XML::LibXML; 
my $foaf = '/xmlns.com/foaf/0.1/'; 
my $rdf = '/www.w3.org/1999/02/22-rdf-syntax-ns#'; 

my $doc = XML::LibXML->new->load_xml(location => 'foof.xml'); 
my $Name = $doc->getElementsByTagNameNS($foaf, 'name')->[0]->textContent; 
my $EmailAddress = $doc->getElementsByTagNameNS($foaf, 'mbox')->[0]->getAttributeNS($rdf, 'resource'); 
$EmailAddress =~ s/^mailto://; 
+0

Я могу получить имя, используя: perl -l -ne '/ (. *) <\\/foaf: name> и print \ $ 1''; – user3616128

+0

У меня нет сомнений, что вы в состоянии это сделать. Это не делает его идеей. Что, если, например, в документе содержится '{' -экранированных символов? Анализаторы XML обрабатывают все эти данные автоматически и правильно. Не изобретайте велосипед плохо. –

+1

XML также имеет множество допустимых способов переформатирования семантически идентичных документов. Это приводит к разрыву разбора на основе строки/регулярного выражения. – Sobrique

1

С xmlstarlet:

Для имени:

xmlstarlet sel -t -v /rdf:RDF/rdf:Description/foaf:name file 

И для электронной почты:

xmlstarlet sel -t -v "/rdf:RDF/rdf:Description/foaf:mbox/@rdf:resource" file 

Вы могли бы добавить ко второму в sed заявление, чтобы удалить mailto часть:

xmlstarlet ... | sed 's/^mailto://g' 
Смежные вопросы