다른 줄의 두 문자열 사이에 나타나는 문자열을 찾는 방법

다른 줄의 두 문자열 사이에 나타나는 문자열을 찾는 방법

다른 문자열(대부분의 경우 몇 줄) 앞에 있고 다른 문자열이 뒤에 오는(예: 특정 환경에 포함된) 특정 문자열을 검색하려면 어떻게 해야 합니까?

\begin{quote}
%several lines of text
\footnote{%
%probably a few more lines of footnote content
}
%several lines of further text
\end{quote}

\footnote{그래서 저는 인용 환경( 로 시작하고 로 \begin{quote}끝나며 end{quote}대부분의 경우 여러 줄에 걸쳐 있음) 내에 포함된 각주(로 시작)를 검색하고 있습니다 . 실제로 참조된 환경 내에서 발생하는 각주에 포함된 다른 환경을 검색하여 두 번째 조건 레이어를 추가해야 하지만 아마도 단순화된 예를 이해하고 나면 실제 질문을 파악할 수 있을 것입니다. 내가 검색한 실제 환경은 .tex며칠 안에 인쇄될 것으로 예상되는 약 500페이지 분량의 책에 대한 소스 코드를 구성하는 약 20개의 파일이 포함된 디렉토리에서 약 150회 검색되었으며, 이러한 특정 조합은 바람직하지 않은 효과를 가져올 수 있으며 여러 번 주의 깊게 살펴보지 않으면 눈에 띄지 않게 될 것입니다.

*tex검색 결과로 일치 항목이 발생한 파일 이름(아마도 검색하겠지만 너무 복잡하면 bash for 루프를 사용할 수도 있음)과 해당 줄 번호를 얻고 싶습니다 .

사람들도 이것을 기억해야 한다

\begin{quote}
%something
\end{quote}
%something
\footnote{%
%something
}
%something
\begin{quote}
%something
\end{quote}

어떤 일이 여러 번 발생하지만 이는 거짓 긍정일 것입니다.

답변1

이를 수행하는 데 사용할 수는 없습니다 . 또는 grep와 같은 더 강력한 기능이 필요합니다 . Perl에서 이 작업을 수행하는 매우 간단한 예는 다음과 같습니다.awkperl

$ cat find-fn-in-quote.pl 
#!/usr/bin/perl

while(<>) {
  # strip comments so that we ignore commented-out quotes & footnotes.
  s/%[^%].*//;

  # detect beginning and end of quotes
  if (m/\Qbegin{quote}\E/) { $qt = 1; $ql = $.};
  if (m/\Qend{quote}\E/)   { $qt = 0 };

  if (eof) {
    # reset line-counter ($.) after every input file
    close(ARGV);

    # reset $qt to zero, in case of unbalanced begin/end{quote}
    $qt = 0;
  };

  # skip to next input line if we're not inside a quote.
  next unless ($qt);

  if (m/\\footnote\{/) {
   print "$ARGV: found footnote beginning on line $. inside quote beginning on line $ql\n";
   # For terse output, comment out or delete the print statement above
   # and un-comment one of these:
   #printf "%s:fn=%i:q=%i\n", $ARGV, $., $ql;
   #printf "%s:%i:%i\n", $ARGV, $., $ql;
  };

};

참고: 이 스크립트는 중첩을 올바르게 처리하지 않습니다 begin{quote}. 인위적인 예가 아닌 경우에는 이런 일이 발생할 가능성이 낮기 때문에 이것이 문제가 될 것이라고 의심됩니다. 또한 참조가 파일 내에 완전히 존재한다고 가정합니다. 실제로 스크립트는 end{quote}한 입력 파일의 오류(예: 부재)가 후속 파일에 영향을 미치지 않도록 의도적으로 이를 강제합니다.

테스트를 위해 3개의 텍스트 파일을 만들었습니다. input1.txt첫 번째 예제 입력이 포함되어 있습니다. input2.txt두 번째 입력 예시와 일치시키고 싶지 않은 거짓 긍정을 포함하세요. input3.txtinput2.txt 다음에 input1.txt가 포함됩니다(즉 cat input2.txt input1.txt > input3.txt). 이러한 입력 파일에 대해 스크립트를 실행하면 다음과 같은 출력이 생성됩니다.

$ ./find-fn-in-quote.pl *.txt
input1.txt: found footnote beginning on line 3 inside quote beginning on line 1
input3.txt: found footnote beginning on line 14 inside quote beginning on line 12

답변2

awk버전

awk 'FNR==1{looking=0; print  FILENAME}
  $0~/begin{quote}/{looking=1;next}
  $0~/end{quote}/{looking=0;next}
  looking&&$0~/footnote{/{print FNR, $0}' *.tex

인용문이 시작되면 "보기"를 시작하고 인용문이 끝나면 "보기"를 중지하세요.

@cas 예제와 마찬가지로 파일을 열 때마다 재설정됩니다.

각주에서 다른 환경을 찾고 있다면 다른 동물인 다른 선 }에서 균형을 찾기 시작해야 하기 때문에 상황이 더 까다로워집니다.\footnote

답변3

GNU awk:

awk '
/^\\end{quote}$/ && fire        {report = report OFS str}
/^\\end{quote}$/                {block=cont=fire=0; str=""}
/^\\begin{quote}$/              {block=1}
block && /^\\footnote{%$/       {cont=1; str=FNR; next}
block && cont && /}/            {fire=1;cont=0}
ENDFILE                         {if(report)print FILENAME report; report = ""}
' *.tex

출력 형식:

filename line_number line_number ...

각 파일에 대해 일치하는 모든 줄 번호가 한 줄에 출력됩니다. 일치하지 않는 파일 이름은 표시되지 않습니다.

관련 정보