[regex] grep, regex 또는 perl을 사용하여 패턴에 따라 문자열을 추출하는 방법

다음과 같은 파일이 있습니다.

    <table name="content_analyzer" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer2" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer_items" primary-key="id">
      <type="global" />
    </table>

나는 따라 따옴표 안에 아무것도 추출해야 name=즉,, content_analyzer, content_analyzer2content_analyzer_items.

Linux 상자에서이 작업을 수행하고 있으므로 sed, perl, grep 또는 bash를 사용하는 솔루션이 좋습니다.



답변

결과에 포함하지 않고 콘텐츠를 일치시켜야하므로 (일치해야 name=" 하지만 원하는 결과의 일부가 아님) 어떤 형태의 제로 너비 일치 또는 그룹 캡처가 필요합니다. 다음 도구를 사용하여 쉽게 수행 할 수 있습니다.

Perl

Perl을 사용하면 n 옵션을 사용하여 한 줄씩 반복하고 일치하는 경우 캡처 그룹의 내용을 인쇄 할 수 있습니다 .

perl -ne 'print "$1\n" if /name="(.*?)"/' filename

GNU grep

GNU grep과 같은 향상된 버전의 grep이있는 경우 -P옵션을 사용할 수 있습니다. 이 옵션은 Perl과 유사한 정규식을 활성화 \K하여 단축형 lookbehind 를 사용할 수 있습니다 . 일치 위치를 재설정하므로 앞의 모든 것은 너비가 0입니다.

grep -Po 'name="\K.*?(?=")' filename

o 옵션은 grep이 전체 행 대신 일치하는 텍스트 만 인쇄하도록합니다.

Vim-텍스트 편집기

또 다른 방법은 텍스트 편집기를 직접 사용하는 것입니다. Vim을 사용하여이를 수행하는 다양한 방법 중 하나는 줄없이 줄을 삭제
name=한 다음 결과 줄에서 내용을 추출하는 것입니다.

:v/.*name="\v([^"]+).*/d|%s//\1

표준 grep

이러한 도구에 액세스 할 수없는 경우 어떤 이유로 표준 grep을 사용하여 유사한 작업을 수행 할 수 있습니다. 그러나 주위를 둘러 보지 않으면 나중에 정리가 필요합니다.

grep -o 'name="[^"]*"' filename

결과 저장에 대한 참고 사항

위의 모든 명령에서 결과는로 전송됩니다 stdout. 다음을 추가하여 파일에 파이핑하여 언제든지 저장할 수 있음을 기억하는 것이 중요합니다.

> result

명령의 끝까지.


답변

정규식은 다음과 같습니다.

.+name="([^"]+)"

그런 다음 그룹화는 \ 1


답변

Perl을 사용하는 경우 XML :: Simple , XML :: Twig 또는 XML :: LibXML 을 구문 분석하는 모듈을 다운로드하십시오 . 바퀴를 재발 명하지 마십시오.


답변

이 목적을 위해서는 정규식보다는 HTML 파서를 사용해야합니다. 다음을 사용하는 Perl 프로그램 HTML::TreeBuilder:

프로그램

#!/usr/bin/env perl

use strict;
use warnings;

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new_from_file( \*DATA );
my @elements = $tree->look_down(
    sub { defined $_[0]->attr('name') }
);

for (@elements) {
    print $_->attr('name'), "\n";
}

__DATA__
<table name="content_analyzer" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
  <type="global" />
</table>

산출

content_analyzer
content_analyzer2
content_analyzer_items


답변

이것은 그것을 할 수 있습니다 :

perl -ne 'if(m/name="(.*?)"/){ print $1 . "\n"; }'


답변

HTML tidy 및 xmlstarlet을 사용하는 솔루션은 다음과 같습니다.

htmlstr='
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
'

echo "$htmlstr" | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
sed '/type="global"/d' |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n


답변

죄송합니다. sed 명령은 물론 tidy 명령보다 우선해야합니다.

echo "$htmlstr" |
sed '/type="global"/d' |
tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n