큰따옴표가 혼란스럽습니다.

큰따옴표가 혼란스럽습니다.

나는 명령을 사용할 때 큰따옴표가 $, `, \를 제외한 모든 것을 문자로 취급한다는 것을 배웠습니다.

다만, 유사한 명령을 사용할 때에는 find -type f -name "*.jpg" *.jpg큰따옴표로 묶인다. 글쎄, 그것은 우리가 *와 하나의 캐릭터로 취급하고 싶다는 것을 의미합니다 .. 따라서 명령은 경로 이름 확장을 구현하는 대신 find이름이 있는 일반 파일을 출력해야 합니다 .*.jpg

경로 이름 확장을 하려면 find -type f -name *.jpg큰따옴표 없이 명령을 입력해야 할 것 같습니다.

그러나 결과는 동일합니다. 이 명령에 큰따옴표를 사용하는 이유는 무엇입니까?

답변1

와일드카드 확장이 작동하는 방식에는 미묘함이 있습니다. .jpg 파일이 포함되지 않은 디렉토리로 변경하고 다음을 입력하십시오.

echo *.jpg

출력됩니다

*.jpg

특히 *.jpg 문자열은 변경되지 않고 그대로 유지됩니다. 그러나 .jpg 파일이 포함된 디렉터리로 변경하는 경우(예를 들어 image1.jpg 및 image2.jpg라는 두 개의 파일이 있다고 가정) echo *.jpg 명령은 출력되지 않습니다.

image1.jpg image2.jpg

그리고 *.jpg가 확장됩니다.

당신이 입력하면

find . -name *.jpg

그리고 이것을 입력하면 디렉토리에 .jpg 파일이 없습니다. find는 ".", "-name" 및 "*.jpg" 인수를 받습니다. 그러나 .jpg 파일(예: image1.jpg 및 image2.jpg)이 포함된 디렉토리에 이 명령을 입력하면 find는 ".", "-name", "image1.jpg" 및 "image2 매개변수를 수신합니다. ." jpg" "이므로 명령이 실제로 실행됩니다.

find . -name image1.jpg image2.jpg

그리고 불평하는 것을 발견했습니다. 따옴표를 생략하면 정말 혼란스러운 것은 .jpg 파일(예: image1.jpg)이 하나만 있는 경우입니다. 그러면 와일드카드 확장이 발생합니다.

find . -name image1.jpg

find 명령은 기본 이름이 image1.jpg인 모든 파일을 찾습니다.

여담: 이는 특정 패턴과 일치하는 파일이 있는지 확인하는 데 유용한 bash 관용구로 이어집니다.

if [ "$(echo *.jpg)" = "*.jpg" ]; then
    # *.jpg has no matches
else
    # *.jpg has matches
fi

하지만 현재 디렉터리에 "*.jpg"라는 파일이 있으면 이 작업이 작동하지 않는다는 점에 유의하세요. 방수 기능을 강화하려면 이렇게 하세요.

if [ "$(echo *.jpg)" = "*.jpg" ] && [ ! -e "*.jpg" ]; then
    # *.jpg has no matches
else
    # *.jpg has matches
fi

(질문과 직접적인 관련은 없지만 와일드카드 확장이 작동하는 방식의 일부 측면을 설명하기 때문에 이것을 추가했습니다.)

답변2

find검색하는 모든 다양한 디렉터리에서 자체 전역 확장을 수행하려면 이름 패턴에서 별표를 이스케이프해야 합니다 . 이스케이프되지 않으면 *쉘이 현재 디렉토리에 대해서만 확장됩니다. 이로 인해 불법 find통화가 발생할 수 있습니다.

관련 정보