여러 줄의 정규 표현식과 일치하는 파일을 검색합니다(pcregrep을 사용하지 않음)

여러 줄의 정규 표현식과 일치하는 파일을 검색합니다(pcregrep을 사용하지 않음)

질문:

pcregrep 없이 파일에서 여러 줄 정규 표현식과 일치하는 항목을 어떻게 찾을 수 있나요?

각 발생 위치를 찾아 인쇄해야 합니다.

불행하게도 pcregrep은 존재하지 않으며 설치할 권한이 없습니다. 다른 대안 등등 grep perl sed python.

검색을 위한 정규식의 예는 다음과 같습니다.

Text\nLine

문맥:

하나의 스크립트는 수십 개의 파일에 수백 MB의 구조화된 텍스트를 제공했지만 불행하게도 여러 가지 이유로 일부 줄이 누락되었습니다. 행이 어디에서 누락되었는지 확인하여 이전 행과 다음 행의 순서를 검색해야 합니다.

Text
Missing //this line is sometimes missing.
Line

편집하다:

가능한 입력

예.txt

Text
Missing
Line

Text
Missing
Line

Text
Line

Text
Missing
Line

가능한 출력:

example.txt, 10행

실패한 시도:

pcregrep 
    # command not found
apt-get install pcregrep 
    # no permission, no su credentials, distro don't provide pcregrep, outdated sources, customer does not want changes on the serve, etc.
sed -r 's#(Text\nLine)#\1#' ./* 
    # print all lines, not only matches, no indication of file or line, etc.
grep 'Text\nLine' ./* 
    # Does not works on multi-lines
sed -n '/Text/,/Line/{p}' ./* 
    # Not the same regex, does not indicate result lines, etc.

답변1

Unix 도구는 일반적으로 줄 지향적이므로 표준 도구 상자를 사용하여 여러 줄 입력에 정규식을 적용할 수 없습니다.

sed찾고 있는 줄을 감지하는 방식으로 파일을 처리하는 것이 가능하지만, 우리는 개별 줄에 대한 작업을 엄격하게 사용하여 이를 수행합니다.

$ sed -n '/^Text/{N;/^Text\nLine/=;D;}' file
10

이 스크립트는 줄 시작 부분에서 문자열을 sed찾습니다 . Text발견되면 다음 줄을 버퍼에 추가하고 \n중간에 줄을 삽입합니다.

이제 버퍼가 일치하면 사용 중인 명령이 ^Text\nLine현재 줄 번호를 인쇄합니다. 줄 번호 출력은 파일의 줄 번호입니다.=sedLine

두 번째 정규식은 파일의 개행 문자와 일치하는 것처럼 보이지만 그렇지 않습니다. 이는 내부 버퍼의 개행 문자와 일치하며 N파일에서 다음 줄을 읽을 때 명령을 사용하여 해당 줄에 넣습니다.

여러 파일에 적용하려면 루프에서 사용할 수 있습니다.

for name in pattern; do
    printf 'Processing %s...\n' "$name"
    sed -n '/^Text/{N;/^Text\nLine/=;D;}' "$name"
done

pattern관심 있는 파일과 일치하는 일반적인 파일 이름 와일드카드 패턴은 어디에 있습니까?

답변2

설치한 경우 다음 모드에서 사용할 vim수 있습니다 .ex

vim -e -s -c 'argdo g/^Text\nLine/#' -c q ./*.txt

상황에 따른 명령 도 참조하세요 z.

vim -e -s -c 'argdo g/^Text\nLine/z#.5' -c q ./*.txt

그러나 이것은 파일 이름을 인쇄하지 않습니다. 덜 효율적인 perl접근 방식은 다음과 같습니다.

perl -l -0777 -ne 'while (/Text\nLine/g) {
   print "$ARGV, line " . ++(() = $` =~ /\n/g)}' ./*.txt

답변3

 perl -ne 'eof and $. = 0 or /^Text/ && ($_ .= <>) =~ /^Line/m && print "$ARGV: $.\n"' ./*

그러면 일치가 발생한 파일 이름과 줄 번호가 인쇄됩니다.

또한 각 파일의 eof에 도달하면 라인 카운터($.)가 재설정됩니다.

관련 정보