perl linha de um forro + linha de correspondência no arquivo e ignorar os caracteres de barra invertida

0

Eu tenho o seguinte arquivo (file1)

mais arquivo1

<?xml version="1.0" encoding="UTF-8"?>

 <apps>
 <app name="UAT/ECC/Global/MES/1206/MRP-S23"  ear="UAT/ECC/Global/MES/1206/MRP-S23.ear" xml="UAT/ECC/Glal/ME/120/MRP- S23.xml"/>
  <app name="OQ/ediedbn/adSFSF/adSFSF-CL" ear="OQ/ebn/aSF/adSF- CL.ear" xml="OQ/ediedbn/adSFSF/adSSF-CL.xml"/>
 <app name="OQ/ediedbn/adaEBS/adOrBS-HR-CL"  ear="OQ/ediedbn/adOraS/araEBS-HR-CL.ear" xml="OQ/eddbn/aOraEBS/adOEBS-   HR-CL.xml"/>
<app name="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" ear="UAT/CZ/LIS/T068_01/LIS-QA-S03.ear" xml="UAT/CZ/LIMS/T068_01/LIMS-QA-S03.xml"/>
 .
 .
 .

e estas são as linhas de exemplos que preciso corresponder no arquivo1

mais arquivo2

OQ-63/ECC/Glal/Interny/Adapter_Services/adOraEBS-NA
OQ-63/ECC/Glal/MES/58,61/ECC-MRP-S20
OQ-63/ECC/Glbal/MES/CZ/adum-CZ-Adapter
OQ-63/EC/Glal/TI/Adaptvices/adTIS

qual é a melhor abordagem na sintaxe do perl one liner para corresponder as linhas do arquivo2 no arquivo1 (e ignorar a barra invertida e outros caracteres incomuns)

Eu tentei isso, mas não funcionou

 a="OQ-63/ECC/Glal/Interny/Adapter_Services/adOraEBS-NA"

 perl -pe '/(^|\s)\Q$ENV{a}\E(\s|$)/'  file1
    
por yael 23.01.2017 / 11:44

2 respostas

0

Sua tentativa teve vários problemas:

  1. perl -pe imprime todas as linhas - você precisa excluir as linhas não correspondentes ou usar -n e a impressão explícita
  2. strings correspondidas são precedidas por aspas, mas você verifica \ s
  3. Para testar, é útil mostrar o arquivo1 com algumas linhas correspondentes ao arquivo2:)

Então, isso funcionará:

a="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" perl -ne '/"\Q$ENV{a}\E"/ && print' file1

Para fazer toda a correspondência em uma linha, você pode fazer:

perl -ne 'BEGIN { open(F2, shift); $re=join("|", map {chomp($_); "\"\Q${_}\E\"";} <F2>);} /$re/ && print' file2 file1
    
por 06.02.2017 / 12:41
0

Isso é XML. Expressões regulares são um mau ajuste para XML , para todos eles parecem que deveriam trabalhar.

Isso ocorre porque o XML é contextual e a expressão regular não é. E o XML tem um monte de variações de formatação que são semanticamente idênticas, mas não combinam com a mesma regex.

Embora - pareça que nenhuma das entradas do seu 'segundo arquivo' corresponde ao seu primeiro arquivo no seu exemplo. Eu estou indo supor que você está querendo combinar o campo 'name' do XML embora. (Você deve evitar 'corresponder a qualquer atributo', se puder).

#!/usr/bin/perl

use strict;
use warnings;

#dumper is only needed for the 'print Dumper' line below
#for debugging. Both can safely be removed. 
use Data::Dumper;
use XML::Twig;

open ( my $match_file, '<', 'file2' ) or die $!;
chomp ( my @matches = <$match_file> ); 
my %lookup = map { $_ => 1 } @matches; 

#or if you want a more pithy one that IMO is a bit harder to understand. 
#my %lookup = map { s/[\r\n]+//gr => 1 } <$match_file>;

print Dumper \%lookup; 

my $twig = XML::Twig -> new -> parsefile ( 'file2' ); 

#xpath is XMLs equivalent of regex, but it's 
#more suited to node and attribute matching. 
foreach my $app ( $twig -> get_xpath ( '//app' ) ) {
   $app -> print if $lookup{$app->att('name')};
   #Alternatively extract a single field. 
   print "XML: ", $app -> att('xml'),"\n";
}

Como um forro? Honestamente, eu não faria, se você quiser fazer ambos a leitura dos jogos - e - a busca / impressão.

Mas, para um único elemento, eu talvez fosse:

a="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" perl -MXML::Twig -e 'XML::Twig -> new ( twig_handlers => { 'app' => sub { $_ -> print if $_ -> att('name') eq $ENV{'a'} } } ) -> parse ( { do {local $/; <> } )'

Mas honestamente - eu preferiria escrever "forma longa" ao invés de tentar encenar alguma mágica em uma única linha - se você tentar ler todos os seus padrões, você acabará com um algoritmo ineficiente, e se você tentar e fazê-los all , então você está fazendo uma leitura de arquivo duplo e uma estrutura de dados no mesmo liner, e isso é apenas confuso.

    
por 08.02.2017 / 12:19

Tags