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
검색할 확장 버전을 전달합니다. 여러 가지 상황이 있을 수 있습니다.
*.txt
현재 디렉터리에 일치하는 파일이 없습니다. find는 리터럴을 사용합니다*.txt
(기본 bash 설정 가정).*.txt
현재 디렉터리에 있는 단 하나의 파일만 일치한다고 가정해 보겠습니다.a.txt
find는 이 파일 이름을 사용하고a.txt
현재 디렉터리에서 시작하는 find라는 이름의 모든 파일과 일치합니다.현재 디렉터리에 일치하는 파일이 여러 개 있습니다
*.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'
.