grep 명령의 성격은 무엇입니까?

grep 명령의 성격은 무엇입니까?

와일드카드 문자 '*'를 사용하여 모든 .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을 찾습니다 . 더 유효한 정규식이지만... 여전히 일치하지 않습니다 .stxtsample.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 mores, 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인수로 전달되기 전에 쉘 글로브가 어떻게 확장되었는지 확인할 때 더 명확해집니다.

관련 정보