
와일드카드 문자 '*'를 사용하여 모든 .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개 이상의 이전에 정의된 개체"를 의미합니다. 그러나.
또한'한 문자'를 의미하는 와일드카드입니다.
쉘 글로브에서는 *
"0개 이상의 문자"를 의미합니다. .
전혀 와일드카드가 아닙니다.
grep
패턴을 찾으려면 0 "*.txt"
개 이상의 항목을 찾고, 그 뒤에 정확히 하나의 문자가 더 오고, 그 뒤에 리터럴 문자열이 옵니다 txt
.
ss txt` grep
패턴을 사용 하는 경우 ."s*.txt"m you are looking for a literal
, followed by zero or more
s, followed by any character, followed by the literal string
이것이 바로 정규식에서 찾을 수 있는 일반적인 사항 중 하나가 입니다 .*
. 이는 "모든 문자 중 하나 뒤에 0개 이상의 문자가 옵니다"를 의미합니다. "문자 그대로 0 문자가 아닌 모든 문자 조합"에 대한 정규식입니다.
쉘 ls *.txt
에 "glob 패턴과 일치하는 파일 이름을 찾아서 *.txt
여기에 나열하고 이를 명령에 대한 인수로 제공하십시오 ls
.
답변3
grep이 파일을 검색 중이라는 점에 유의하세요.콘텐츠첫 번째 인수는 검색 PATTERN이고 다른 인수는 조사할 FILES로 해석됩니다.
grep -H -o
플래그를 사용하거나 grep
스크립트 내부에 넣고 실행하여 bash -x script
인수로 전달되기 전에 쉘 글로브가 어떻게 확장되었는지 확인할 때 더 명확해집니다.