"find"에서 인용 매개변수는 무엇을 합니까? [복사]

"find"에서 인용 매개변수는 무엇을 합니까? [복사]

txt 파일을 찾을 때 다음 명령을 실행합니다.

find . -name "*.txt" -print

그러면 현재 디렉터리에 있는 모든 텍스트 파일의 목록이 제공됩니다.

그러나 find . -name *.txt -print다음과 같은 오류가 발생했습니다. find: paths must precede expression: mein.txt

이것이 일반적으로 예상되는 동작입니까? 인용문의 차이점은 무엇인가요?

답변1

따옴표가 없는 토큰에서는 실행 중인 명령이 아닌 셸에서 확장이 수행됩니다.

find . -name "*.txt" -print, 사용자가 입력할 때 find는 리터럴을 *.txt인수 중 하나로 받고 이 패턴을 옵션에 대한 인수로 사용하며 -name이는 응용 프로그램 이전에 찾은 파일 이름과 일치합니다 -print.

반면에 를 입력하면 find . -name *.txt -print셸은 *.txt검색할 확장 버전을 전달합니다. 여러 가지 상황이 있을 수 있습니다.

  1. *.txt현재 디렉터리에 일치하는 파일이 없습니다. find는 리터럴을 사용합니다 *.txt(기본 bash 설정 가정).

  2. *.txt현재 디렉터리에 있는 단 하나의 파일만 일치한다고 가정해 보겠습니다. a.txtfind는 이 파일 이름을 사용하고 a.txt현재 디렉터리에서 시작하는 find라는 이름의 모든 파일과 일치합니다.

  3. 현재 디렉터리에 일치하는 파일이 여러 개 있습니다 *.txt(귀하의 경우인 것 같습니다). -name첫 번째 파일을 인수로 받고, 다른 파일은 찾을 추가 경로 인수이며, 표현식 앞에 모든 경로를 제공하지 않는다고 불평합니다.

이는 예상된 동작입니다.


우리는 다음과 같은 파일 계층 구조를 가정합니다.

.
├── a.txt
├── b.txt
├── c.txt
└── foo
    ├── a.txt
    ├── b.txt
    └── c.txt

각 경우에 find 가 받은 실제 인수는 find 호출을 로 대체하여 관찰할 수 있습니다 printf '%s\n'. 이 호출은 각 확장 인수를 자체 줄에 인쇄합니다.

$ printf '%s\n' . -name "*.txt" -print
.
-name
*.txt
-print

$ printf '%s\n' . -name *.txt -print
.
-name
a.txt
b.txt
c.txt
-print

보시다시피 기존 파일을 고려하면 게시한 두 번째 호출은 find . -name a.txt b.txt c.txt -print.

답변2

이는 예상된 동작입니다. 이를 "쉘 글로빙(shell globbing)"이라고 합니다. 따옴표가 없으면 *.txt쉘이 확장되어 표현식과 일치하는 전체 파일 목록을 find명령에 전달합니다. 이를 따옴표로 묶으면 셸에 리터럴 문자열을 에 전달하도록 지시할 수 있습니다 *.txt. find다른 이스케이프 방법(예: find . -name \*.txt또는 )을 사용하여 동일한 보호를 얻을 수 있습니다 find . -name '*.txt'.

관련 정보