큰따옴표와 작은따옴표 안의 Grep 문자열

큰따옴표와 작은따옴표 안의 Grep 문자열

텍스트 파일에서 큰따옴표나 작은따옴표 안의 문자열을 찾고 싶습니다(텍스트 파일은 여러 줄입니다).

예를 들어:

I have a 
test "foo bar1" test2 "foo\"bar2", 
"foo 'bar3", 
'foo bar4', 'foo \'bar5', 'foo "bar6',

출력됩니다

foo bar1
foo\"bar2
foo 'bar3
foo bar4
foo \'bar5
foo "bar6

난이도는 다음과 같습니다.

  1. 텍스트 파일은 여러 줄입니다.
  2. 큰따옴표나 작은따옴표를 따옴표 안에 이스케이프 처리했을 수 있습니다.
  3. 큰따옴표 안에 작은따옴표를 넣을 수 있습니다.
  4. 작은따옴표 안에 큰따옴표가 있을 수 있습니다.
  5. 따옴표는 쌍으로 일치해야 합니다.

답변1

Perl의 일치 시간 코드 보간 기능을 사용하여 (??{ match time regex })이 문제를 해결할 수 있습니다. 기본적으로 이것이 수행하는 작업은 일치하는 참조를 기반으로 정규식 엔진이 해당 참조 쌍을 캡처할 수 있도록 해당 참조에 해당하는 유효한 정규식을 배치하는 것입니다.

$ perl -lne '
    print substr($&, 1, -2+length($&))
      while
         /(?:(["'\''])(??{q<(?:[^\\\\>.$1.q<]|\\\\.)*>.$1}))/gx;
' file

결과:

foo bar1
foo\"bar2
foo 'bar3
foo bar4
foo \'bar5
foo "bar6

위의 내용을 보다 원활하게 다시 작성하면 다음과 같습니다.

$ perl -lne '
    BEGIN {
       $genRE = sub {
          my $openingQ = shift;
          # look in the Notes below for why
          qq<(?:[^\\\\${openingQ}]|\\\\.)*>
       };
    }
    print $2
      while 
        /
         (["'\''])               (?#: opening quote) 
          ((??{ $genRE->($1) })) (?#: run of in between quote pair stuff) 
         \1                      (?#: corresponding closing quote)
        /gx;
' file

노트::

  • "........"성냥/"[^"]*"/
  • "...... \"......"성냥/"(?:[^\\"]|\\.)*"/
  • 작은따옴표도 비슷합니다.

답변2

또 다른 perl방법:

perl -lne 'print $2 while m{(["'\''])((?:\\.|(?!\1).)*+)\1}g'

부정 예측 연산자는 여기서 (?!\1).첫 번째 캡처링 그룹과 일치하는 문자 이외의 문자를 일치시키는 데 사용됩니다. 간단히 재정의 '...'하고 대소문자를 구분할 수도 있습니다 "...".

perl -lne 'print $1 while m{(?|"((?:\\.|[^"])*+)"|'"'((?:\\\.|[^'])*+)')}g"

답변3

이건 어려워. 나는 해결책이 없습니다. 이 작업에 가장 적합한 도구가 무엇인지조차 모르겠습니다.

나는 가깝다:

$ grep -oP '((?<!\\)"\K.*?(?=(?<!\\)"))|'"((?<!\\\\)'\K.*?(?=(?<!\\\\)'))" input

foo bar1
foo\"bar2
foo 'bar3
foo bar4
, 
foo \'bar5
, 
foo "bar6

한 줄에 여러 개의 일치 항목이 있는 경우 앞 문자열의 닫는 따옴표가 중간 텍스트의 시작 따옴표와 일치한다는 문제가 있습니다. 뒤돌아보기는 고정된 길이여야 하기 때문에 짝수 개의 따옴표를 사용하여 긍정적인 뒤돌아보기를 중지할 수 없습니다. 적어도 grep.

'게다가, 그 안에 있는 몇몇 경기(또는 그 반대)도 "아무리 말해도 흥미롭습니다.

어쩌면 awk더 나은 도구일 수도 있습니다. 이를 통해 어떤 참조 유형이 먼저 나오는지 확인하고 다음 참조 유형으로 건너뛰어 앞에 백슬래시가 있는지 확인할 수 있습니다.

관련 정보