내 문제의 원인은답은 이 링크에 있습니다, 그리고 추가 내용
고쳐 쓰다
즉, 첫 번째 명령은 이해 grep \\[[a-z\|1-9]*\\] file
하지만 두 번째 명령의 출력은 이해하지 못합니다 grep \[[a-z\|1-9]*\] file
.
이제 두 번째 명령의 출력이 어떻게 구성되는지, 특히 grep이 세 번째와 네 번째 줄 전체를 선택하지만 첫 번째 줄까지 두 번째와 세 번째 줄만 선택하는 이유를 이해하고 싶습니다.]
답변1
귀하의 질문에 철저하게 답변하기에는 너무 많은 변수와 명시되지 않은 가정이 있습니다.
여기서 가장 큰 함정은 쉘(즉, 대부분의 Bourne 호환 쉘 - zsh 또는 csh 및 그 파생물에 대해 확실하지 않음)이 기본적으로 확장되지 않은 glob을 전달한다는 것입니다.아무것도 일치하지 않는 경우.따라서 먼저 이와 같은 표현식을 \\[[a-z0-9]*\\]
와일드카드로 사용해 보십시오.만약에일치하지 않는 파일의 경우(예: 문자가 아닌 모든 단어는 리터럴임) 와일드카드가 그대로 전달 \fno[rd\]
됩니다 .grep
(이것을 다시 확인해 보겠습니다. 이것은 이중 백슬래시입니다. 즉, 인용된 리터럴 백슬래시 뒤에 두 개의 왼쪽 대괄호가옵니다. 첫 번째 문자는 첫 번째 문자가 두 번째 문자인 문자 클래스를 만듭니다 [
. 이를 정규식으로 구문 분석한 결과는 다음과 같습니다. 다르지만 똑같이 수수께끼입니다).
이에 대한 유일한 합리적인 해결책은 쉘에 의한 공백 토큰화 및 와일드카드 확장이 필요하지 않은 항목을 적절하게 인용하는 것입니다. 내 제안은 모든 정규식에 작은따옴표를 사용하는 것입니다. 그러면 별도의 노력을 하지 않고도 무엇을 어떻게 일치시킬지에 대한 합리적인 기대치를 형성할 수 있습니다.둘패턴(셸, 정규식)에 대한 전문적인 해석입니다.
정확한 일치를 원하는 경우 var[1]
정규식은 [a-z]*\[[0-9]*\]
비슷한 작업을 수행할 수 있습니다 . 대괄호를 문자 클래스의 일부로 사용하려면 [][a-z0-9]*
첫 번째 ]
와 두 번째가 [
문자 클래스의 리터럴 멤버인지 시도해 보세요. 이를 grep
쉘 에 전달하는 경우 주위에 있는 작은따옴표를 기억하십시오.
답변2
천천히 가자. 다음 내용이 포함된 파일이 있는 경우(표시하기 쉽도록 한 줄만 사용):
$ cat infile
list[1]; i[ab1]; var[1] [1]var [1]var[2]
ㅏ
Simple은 grep --color a
모든 a를 빨간색으로 표시합니다. (사이트에서 색상 제어를 허용하므로 굵은 글씨가 빨간색이라고 가정):
$ grep --color a infile
list[1]; i[
ㅏb1]; v
ㅏr[1] [1]v
ㅏr [1]v
ㅏr[2]
a 가 (위와 같이) 인용되지 않거나 인용된 경우에도 똑같은 일이 발생합니다.
$ grep --color \a infile
list[1]; i[
ㅏb1]; v
ㅏr[1] [1]v
ㅏr [1]v
ㅏr[2]
$ grep --color "a" infile
list[1]; i[
ㅏb1]; v
ㅏr[1] [1]v
ㅏr [1]v
ㅏr[2]
$ grep --color 'a' infile
list[1]; i[
ㅏb1]; v
ㅏr[1] [1]v
ㅏr [1]v
ㅏr[2]
왜? 왜냐하면 a는둘 다:
- 껍질에는 특별한 것이 없습니다.
- 쉘은 따옴표를 제거하고 grep은
a
첫 번째 인수와 동일한 내용을 받습니다. 백슬래시 따옴표, 큰따옴표 또는 작은따옴표입니다.
]
중괄호를 선택하려면 ]
(닫는 중괄호부터 시작하겠습니다):
$ grep --color ] infile
list[1
]; i[ab1
]; var[1
][1
]var [1
]var[2
]
]
참조(모든 참조)가 있는 경우에도 동일한 일이 발생합니다.
이 경우에는 ]
쉘에 특별하지만 일치하는 여는 중괄호가 없는 경우에는 그렇지 않습니다.
닫는 중괄호의 경우 상황이 더 복잡해집니다. 이러한 모든 오류는 다음과 같습니다.
grep --color [ infile
grep --color '[' infile
grep --color "[" infile
왜? grep으로 받은 콘텐츠 때문에모두사건은 특이하다 [
.
이 간단한 에코를 통해 쉘이 수행하는 작업을 확인할 수 있습니다.
$ echo \[ "[" '['
[ [ [
셸은 첫 번째 수준 참조를 제거하고 모든 값은 동일하게 보입니다.
[
그러나 grep이 얻고자 하는 것은 우리가 실제로 검색하는 문자가 [
백슬래시로 묶인 대괄호( \[
)라는 것을 이해하는 것입니다. 이 모든 일이 발생합니다.
$ echo \\[ "\[" '\['
\[ \[ \[
grep은 다음 중 하나와 함께 사용할 수 있습니다.
$ grep --color \\[ infile
list
[1]; i
[ab1]; var
[1]
[1]var
[1]var
[2]
[[]
(단 하나의 문자만 포함하는 문자 목록)을 사용하면 [[]
동일한 결과를 얻을 수 있습니다(따옴표가 있는 한).
$ grep --color '[[]' infile
list
[1]; i
[ab1]; var
[1]
[1]var
[1]var
[2]
[[]
Grep이 제대로 작동하려면 정확한 수신이 필요합니다 . 따옴표가 필요하지 않은 것 같습니다.
$ echo \[\[\] "[[]" '[[]' [[]
[[] [[] [[] [[]
그러나 다음과 같은 파일을 생성하면 [
이 아이디어는 깨집니다 .
$ touch \[
$ echo \[\[\] "[[]" '[[]' [[]
[[] [[] [[] [
그것은 [
껍질에 특별하기 때문입니다. 쉘의 경우 파일 이름 글로빙 모드를 활성화합니다. 하나 이상의 파일이 패턴과 일치하면 파일 목록이 대체됩니다.
따라서 다음은 올바르게 작동합니다.
$ grep --color '[[]' infile
list
[1]; i
[ab1]; var
[1]
[1]var
[1]var
[2]
그리고 이것은: grep --color '[]]' infile
닫는 중괄호와 일치합니다.
[][]
왼쪽 대괄호 일치그리고닫는 대괄호 안에는 특정 문자 시퀀스(물론 따옴표 포함)가 필요합니다.
이것을 시도하면:
$ grep --color '[[]]' infile
게임은 전혀 없을 것입니다. 작동하려면 다음이 필요합니다.
$ grep --color '[][]' infile
list
[1
]; i
[ab1
]; var
[1
][
1
]var
[1
]var
[2
]
이 특정 순서에서 닫는 중괄호는 문자 범위의 첫 번째 문자여야 합니다. 여는 중괄호는 문자 목록의 마지막 문자여야 합니다.
[]a-z0-9[]
그런 다음 추가 문자를 추가할 수 있습니다(그 이상은 추가할 수 없음 ;
).
$ grep --color '[]a-z0-9[]' infile
목록[1];
나[ab1];
변수[1][1]변수
[1]변수[2]
|
그런 다음 범위에서 누락된 항목을 추가하고 게시한 링크와 일치하도록 만들 수 있습니다. 해당 링크의 정규식은 여기와 다르며 매우 다른 방식으로 작동합니다. one 과 다른 문자를 일치시키는 것으로 시작 [
하고 종결자로 끝납니다 ]
. 다음과 같은 것(탐욕스러운 성격이 *
전체 라인을 차지합니다):
$ grep --color '\[.*\]' infile
list
[1];i[ab1];변수[1][1]변수[1]변수[2]
아니면 다음과 같습니다:
$ grep --color '[[][a-c0-9]*[]]' infile
list
[1]; i
[ab1]; var
[1][1]
var
[1]var
[2]`