Perl 파일의 + 라인은 라인과 일치하고 백슬래시 문자를 무시합니다.

Perl 파일의 + 라인은 라인과 일치하고 백슬래시 문자를 무시합니다.

다음 파일이 있습니다 ( file1 )

더 많은 파일 1

<?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"/>
 .
 .
 .

다음은 file1에서 일치시켜야 하는 예제 줄입니다.

더 많은 파일 2

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

file1의 file2에 있는 행을 일치시키고 백슬래시 및 기타 일반적이지 않은 문자를 무시하기 위해 Perl oneliner 구문에 대한 가장 좋은 접근 방식은 무엇입니까?

이것을 시도했지만 작동하지 않습니다

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

 perl -pe '/(^|\s)\Q$ENV{a}\E(\s|$)/'  file1

답변1

시도에 몇 가지 문제가 있습니다.

  1. perl -pe는 모든 줄을 인쇄합니다. 일치하지 않는 줄을 제거하거나 -n을 사용하고 명시적으로 인쇄해야 합니다.
  2. 일치하는 문자열 앞에는 따옴표가 붙지만 \s를 확인하세요.
  3. 테스트를 위해 file1과 file2와 일치하는 일부 행을 표시하는 것이 유용합니다. :)

그래서 이것은 작동합니다 :

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

한 줄에서 모든 일치를 수행하려면 다음을 수행할 수 있습니다.

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

답변2

이것은 XML입니다. 정규 표현식은XML에는 적합하지 않음, 작동해야 하는 것처럼 보이지만.

그 이유는 XML은 상황에 민감하지만 정규식은 그렇지 않기 때문입니다. XML에는 의미상 동일하지만 동일한 정규식과 일치하지 않는 여러 가지 형식 차이가 있습니다.

하지만 "두 번째 파일" 항목 중 어느 것도 예제의 첫 번째 파일과 일치하지 않는 것 같습니다. XML의 "이름" 필드와 일치시키려는 것 같습니다. (가능하다면 "모든 속성과 일치"를 피해야 합니다).

#!/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";
}

라이너로? 솔직히 네가 원한다면 그러지 않을 거야둘 다일치 항목을 읽고 검색/인쇄합니다.

그러나 단일 요소의 경우 다음을 선택할 수 있습니다.

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 $/; <> } )'

하지만 솔직히 - 나는 한 줄로 마법을 걸기보다는 "긴 형식"으로 쓰는 것을 고수할 것입니다.모두패턴을 사용하려고 하면 결국 비효율적인 알고리즘을 사용하게 될 것입니다.모두그러면 동일한 라이너에 이중 파일 읽기 및 데이터 구조가 있어 너무 혼란스럽습니다.

관련 정보