여러 줄 정규식이 수십 번 논의되었다는 것을 알고 있지만 내 패턴에 맞게 작동할 수는 없습니다.
나는 설명하려고 노력할 것이다. 내 디렉토리에 일부 텍스트 파일이 있습니다. 파일의 텍스트 예:
LINE OF TEXT 2
LINE OF TEXT 1
LINE OF TEXT 3
LINE OF TEXT 1
LINE OF TEXT 2
LINE OF TEXT 3
LINE OF TEXT 1
LINE OF TEXT 3
LINE OF TEXT 3
LINE OF TEXT 2
LINE OF TEXT 1
LINE OF TEXT 2
LINE OF TEXT 3
"LINE OF TEXT 1"(사이에 빈 줄 없음) 뒤에 오는 "LINE OF TEXT 2" 뒤에 오는 "LINE OF TEXT 3"을 찾고 싶습니다.
각 줄 자체는 정규식이어야 합니다(예: "LINE"으로 시작하고 특정 숫자로 끝나는 줄).
참고: 모든 파일에 정확한 행 순서가 포함되어 있는 것은 아니므로 패턴이 일치하면 패턴이 인쇄되지 않고 파일 이름만 STDOUT에 인쇄됩니다.
한 줄 정규식으로 이 작업을 수행할 수 있습니까? 예를 들어 awk는 파일에서 패턴을 검색하고 패턴이 발견되면 파일 이름을 STDOUT에 인쇄합니다. 그런 다음 "find -exec"와 함께 이 정규식을 사용할 수 있습니다.
언급된 모든 도구(grep, awk, sed 또는 perl)가 가능합니다.
답변1
Awk를 사용하여 "Record Separator" 변수를 최소 두 개의 연속 개행 문자와 일치하는 정규식으로 설정하여 이 작업을 수행할 수 있습니다.
awk -v RS='\n\n+' '/1.*2.*3/' file.txt
필드 구분 기호를 단일 개행 문자로 설정할 수도 있습니다.
awk -v RS='\n\n+' -F '\n' '$1 == "LINE OF TEXT 1" && $2 == "LINE OF TEXT 2" && $3 == "LINE OF TEXT 3"' file.txt
읽기 쉽도록 분류:
awk -v RS='\n\n+' -F '\n' '
$1 == "LINE OF TEXT 1" &&
$2 == "LINE OF TEXT 2" &&
$3 == "LINE OF TEXT 3"
' file.txt
일치하는 항목이 발견된 경우에만 파일 이름을 인쇄하도록 하려면 다음을 수행할 수 있습니다.
awk -v RS='\n\n+' -F '\n' '
$1 == "LINE OF TEXT 1" &&
$2 == "LINE OF TEXT 2" &&
$3 == "LINE OF TEXT 3" {
match++
}
END {
if (match) {
print FILENAME
}
' file.txt
하지만 당신이 말하는 것을 고려하면find
와 함께awk
, 종료 상태와 인쇄에는 Awk를 사용하는 것이 좋습니다 find
.
find . -type f -exec awk -v RS='\n\n+' -F '\n' '
$1 ~ /LINE OF TEXT 1/ &&
$2 ~ /LINE OF TEXT 2/ &&
$3 ~ /LINE OF TEXT 3/ {
exit 0
}
END { exit 1 }
' {} \; -print
이렇게 하고 싶은 일이 있으면기타find
인쇄하기 전에 이미 이 작업을 수행할 준비가 되어 있습니다 (다른 주요 작업).
답변2
Perl에서는 "단락 모드"를 사용할 수 있습니다. 이 모드는 개행으로 구분된 여러 청크로 파일을 읽습니다. 입력 레코드 구분 기호로 빈 문자열을 설정하면 됩니다 $/
.
perl -lne 'BEGIN { $/ = "" }
$found = 1 if /^LINE.* 1\nLINE.* 2\nLINE.* 3$/m;
if (eof) { print $ARGV if $found; undef $found }
' -- file1 file2...
eof
모든 파일의 끝에서 true$ARGV
현재 열려 있는 파일의 이름입니다.
답변3
함께 작동하는 find<->perl 조합을 사용하여 이 작업을 수행할 수 있습니다. 예를 들면 다음과 같습니다.
find . -type f -exec \
perl -l -0777ne '/^LINE.* 1\nLINE.* 2\nLINE.* 3$/m && print $ARGV' {} +