긴 문장으로 요약하겠습니다.
(foo),(bar,baz(word,right),(end)
나는 단지 인쇄하고 싶습니다 :
(bar,baz(word,right
두 번째 대괄호를 일치시키기 위해 나는들어오지 못하게 하다세 번째 단어 다음의 단어:
$ grep -oP "\\(.*(?!word).*right"
그러나 Bash는 느낌표를 설명합니다.
-bash: !word: 이벤트를 찾을 수 없음
느낌표 보호아포스트로피실패한grep: missing )
$ grep -oP '\\(.*(?!word).*right'
$ grep -oP '\\((?!word)(.*right)'
느낌표 보호백슬래시실패한grep: unrecognized character after (? or (?-
어떤 아이디어가 있나요?
참고: -P
Perl 정규식의 경우 -o
행에서 일치하는 부분만 인쇄됩니다.
답변1
작은따옴표와 큰따옴표의 규칙은 다릅니다.
표시된 이유로 인해 느낌표를 이스케이프 처리할 수 있는 합리적인 방법이 없기 때문에 bash에서는 큰따옴표를 안정적으로 사용할 수 없습니다.
$ grep -oP "\\(.*(?!word).*right"
bash: !word: event not found
$ grep -oP "\\(.*(?\!word).*right"
grep: unrecognized character after (? or (?-
두 번째는 bash가 grep \!
대신 전달하기 때문입니다 !
. 이것을 보여주세요:
$ printf '%s' "\!"
\!
작은따옴표를 사용하려고 할 때 이중 백슬래시는 이스케이프된 백슬래시를 의미하는 것이 아니라 두 개의 백슬래시를 의미합니다.
$ printf '%s' '\\(.*(?!word).*right'
\\(.*(?!word).*right
작은 따옴표 내에서는 모든 것이 문자 그대로이고 이스케이프되지 않으므로 시도하려는 정규식을 작성하는 방법은 다음과 같습니다.
$ grep -oP '\(.*(?!word).*right'
답변2
두 번째 여는 괄호부터 다음 닫는 괄호까지(포함하지 않음) 일치시키려는 경우:
grep -Po '\(.*?\K\([^)]*'
또는 휴대용으로 사용하십시오 sed
.
sed -n 's/^[^(]*([^(]*\(([^)]*\).*/\1/p'
(
가장 오른쪽 항목이 뒤따르지 않는 가장 오른쪽 항목과 일치시키려면 다음을 수행하세요 word
.right
grep -Po '.*\K\((?!word).*right'
답변3
간단한 방법으로 이 작업을 수행할 수 있습니다 awk
.
$ echo '(foo),(bar,baz(word,right),(end)' | awk -F'),' '{print $2}'
(bar,baz(word,right
답변4
어떤 이유로 Mikel의 답변에서 제안한 대로 작은따옴표를 사용할 수 없는 경우 Glenn jackman이 의견에서 제안한 대로 기록 확장을 일시적으로 해제하는 데 사용할 수 있습니다 set +H
(openor 사용 ).set -H