와일드카드 "*"를 사용하여 모든 .txt 파일을 grep하고 싶습니다.
이 명령을 시도했지만(따옴표 "" 없이) 실패했습니다.
ls | grep "*.txt"
흥미롭게도 디렉터리의 .txt 파일에 해당하는 grep 명령에 다른 문자를 넣으면 작동합니다.
>>ls | grep s*.txt
sample.txt
나는 이것이 ls *.txt
작동할 것이라는 것을 알고 있었지만 grep 명령의 특성에 조금 놀랐습니다. 왜 이런 일이 발생하는지 도와줄 수 있는 사람이 있나요?
grep이 정규식을 사용하기 때문인가요? 도와주세요.
답변1
정규식에서는 *
쉘 모드에서와 같이 "임의의 문자 수"가 아니라 "이전 항목의 수"를 의미합니다. "모든 단일 문자"를 의미 합니다 .
. 따라서 "텍스트 뒤에 오는 모든 것 .txt
" 을 찾으려면 .*\.txt
. \.txt
그런 다음 끝에 올 필요가 없으므로 유사한 \.txt
파일 이름도 일치합니다 . 패턴을 줄 끝까지 잠가야 합니다 .foo.txtgz
.txt
\.txt$
정규식은 *.txt
구현 및 기본 정규식( grep
) 또는 확장 정규식( grep -E
)을 사용하는지 여부에 따라 의미가 없거나 잘못되었거나 문자 그대로 별표를 찾습니다. 사용하지 않는 것이 좋습니다.
반면에 "문자 수 , 단일 문자, 리터럴 " s*.txt
을 찾습니다 . 이것은 더 효율적인 정규식이지만... 여전히 일치하지 않습니다 .s
txt
sample.txt
대신, 두 번째 명령에서는 인용되지 않았기 때문에 s*.txt
쉘이 그것을 보기 전에 s*.txt
확장합니다 . grep
일치하는 유일한 파일이 sample.txt
이면 grep
의 출력에서 해당 파일을 찾으십시오 ls
. (일치하는 파일 이름이 여러 개인 경우 첫 번째 파일은 패턴으로 처리되고 나머지는 파일 이름으로 읽혀집니다 grep
. 이 경우 파이프의 입력을 무시합니다.)
그러나 ls
파일 목록을 얻는 것도 가능하므로 다음을 사용할 수 있습니다.
ls | grep '\.txt'
파일을 얻으려면 .txt
사용하기가 더 쉬울 수 있습니다.
ls *.txt
대신에.
답변2
그 중 일부는 정규 표현식을 사용했기 때문입니다 grep
(사실 re
이름이 의미하는 바는 바로 이것이다.G글로벌아르 자형정기적인이자형표현하다피인쇄).
정규식의 와일드카드 문자는 *
셸 와일드카드의 와일드카드 문자와 다릅니다.*
정규식에서 *
"0개 이상의 이전에 정의된 개체"를 의미합니다. 그러나 .
그것은반품"문자"를 의미하는 와일드카드입니다.
Shell glob에서는 *
"0개 이상의 문자"를 의미합니다. .
전혀 와일드카드가 아닙니다.
grep
패턴을 검색할 때는 "*.txt"
0개 이상의 항목을 찾고 그 뒤에 문자, 마지막으로 리터럴 문자열을 찾습니다 txt
.
grep
패턴 "s*.txt"m you are looking for a literal
s txt` , followed by zero or more
를 사용하는 경우 s, followed by any character, followed by the literal string
.
그렇기 때문에 정규식에서 흔히 볼 수 있는 것은 .*
"모든 문자 중 하나 뒤에 0개 이상의 문자가 오는 것"을 의미한다는 것입니다. 정규식은 "실제로 0 문자를 제외한 모든 문자 조합"입니다.
ls *.txt
쉘에 "글로브 패턴과 일치하는 파일 이름을 찾으세요"라고 지시할 때 , 여기에 나열하고 명령 *.txt
에 대한 인수로 제공하십시오 .ls
답변3
grep이 파일을 검색하고 있다는 점에 유의하세요.콘텐츠첫 번째 매개변수는 검색 모드이고, 다른 매개변수는 볼 파일로 해석됩니다.
플래그를 사용 하거나 이를 스크립트 grep -H -o
에 넣고 실행하여 인수로 전달되기 전에 쉘 글로브가 어떻게 확장되는지 확인 하면 더 명확해집니다.grep
bash -x script