다음 구조와 일치하는 파일의 텍스트 부분을 표시하기 위해 패턴 일치를 수행하고 싶습니다.
## DN [Pattern-Matching] glob,regex
## Some text
## More text
## DN [Pattern-Matching] ends here
문법
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here
제목에서 TITLE은 키워드(쉼표로 구분된 여러 키워드)와 함께 사용됩니다.
이 섹션을 표시하려면 사용자가 TITLE
또는 를 제공합니다 KEYWORD
.
다음 태그로 시작하세요
lab="## DN [Something]"
위에서 완성한 패턴과 일치합니다.
if [[ "$lab" =~ ^[[:space:]]*([#;!]+|@c|//)[[:space:]]DN[[:space:]]\[.*\]$ ]]; then
이제 추가 키워드 부분을 일치시켜야 합니다.
마지막으로 맞추고 싶은 부분은keyword,keyword
나는 이 일을 시작했습니다 ([^,]+)
. 내 혼란은 ,keyword
이 이후에 0개 이상의 남은 가능성을 일치시키는 것입니다 .
답변1
텍스트 처리에는 bash가 아닌 awk 또는 perl을 사용하십시오.
예를 들어 awk를 사용하면 다음과 같습니다.
awk '/^[[:blank:]]*##[[:blank:]]+DN[[:blank:]]+\[TITLE\]/ {
if (p) print;
p = ! p
};
p' input.txt
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here
그런데 awk에 익숙하지 않다면 p
awk 스크립트에서 세미콜론 뒤의 마지막 항목이 p
true인지 테스트하고 true인 경우 현재 줄을 인쇄합니다 {if (p) print}
. 즉, awk 스크립트는 awk 스크립트로 구성됩니다. 일련의 "PATTERN ACTION" 규칙으로, PATTERN 또는 ACTION은 생략될 수 있습니다. 패턴은 참 또는 거짓으로 평가되는 모든 것입니다. PATTERN을 생략하면 기본값은 true입니다. 즉, 항상 ACTION이 실행됩니다. ACTION은 실행할 awk 코드입니다. ACTION을 생략하면 기본값은 ACTION입니다 print
.
아니면 펄을 사용하세요:
$ perl -ne 'if (/^\h*##\h+DN\h+\[TITLE\]/) {
print if $p;
$p = ! $p
};
print if $p' input.txt
## DN [TITLE] KEYWORD[,KEYWORD..]
## Some text
## More text
## DN [TITLE] ends here
두 스크립트 모두 동일한 방식으로 작동합니다. 즉, 서로를 직접 번역하는 것입니다.
두 스크립트 모두에서 변수 p
( $p
perl의 경우)는 패턴이 표시될 때 인쇄를 켜고 끄는 토글 스위치로 사용됩니다.
두 스크립트 모두 일부 코드 중복이 필요합니다. 전환 p
(또는) 하는 코드 블록은 참 $p
인지 확인 p
하고 참이면 인쇄해야 합니다.앞으로스위치 p
. 그렇지 않으면 p
"p가 true인 경우 인쇄" 테스트를 수행하기 전에 닫히기 때문에 원하는 블록의 마지막 줄이 인쇄되지 않습니다 .
참고: [[:blank:]]
공백이나 탭을 나타냅니다. 펄 \h
의미어느가로 공백(로케일에 따라 일부 유니코드 공백 문자 포함) 실제로 둘 다 ASCII 텍스트에 동일한 효과를 갖습니다.
두 가지 조건을 테스트해야 하는 경우 두 가지 변수( 예를 들어 p1
및 p2
(그리고 perl 의 경우 $p1
))를 사용하십시오. $p2
별도로 테스트하고 둘 다 참인 경우에만 인쇄합니다(예: p1 && p2
awk, print if ($p1 && $p2)
perl).
쉘 변수는 명령줄이나 환경 변수( export
모든 하위 프로세스의 환경에서 사용 가능한 bash의 변수)를 통해 쉘에서 awk 또는 perl로 전달될 수 있습니다.