나는 몇 가지 파일 작업을 수행하기 위한 스크립트를 작성했습니다. 와일드카드 연산자를 사용하여 *
특정 유형의 모든 파일에 함수를 적용하고 있는데 한 가지 이해되지 않는 것이 있습니다. unzip
이런 폴더에 있는 모든 파일을 사용할 수 있습니다 .
unzip "*".zip
그러나 나중에 모든 zip 파일을 제거하려면 다음을 수행해야 합니다.
rm *.zip
즉, 따옴표를 원하지 않습니다. 반면에 *만 입력하면 압축 해제가 작동하지 않습니다("파일이 일치하지 않습니다"라는 경고 표시).
이것이 왜 다른가요? 나에게 이것은 똑같은 작업처럼 보입니다. 아니면 와일드카드를 잘못 사용하고 있는 걸까요?
와일드카드 소개rm
유닉스에서는 실제로 이에 대해 다루지 않으며 또는 문서 에서 아무것도 찾을 수 없습니다 zip
.
Mac(Yosemite)에서 터미널을 사용하고 있습니다.
답변1
상황을 아주 잘 설명해주셨네요. 퍼즐의 마지막 조각은 unzip
와일드카드 자체를 처리할 수 있다는 것입니다.
http://www.info-zip.org/mans/unzip.html
인수
파일[.zip]
...
와일드카드 표현식은 일반적으로 사용되는 Unix 셸(sh, ksh, csh)에서 지원되는 표현식과 유사하며 다음을 포함할 수 있습니다.
*는 0개 이상의 문자 시퀀스와 일치합니다.
* 와일드카드를 인용하면 쉘이 확장하는 것을 방지할 수 있으므로 unzip
쉘은 와일드카드를 보고 자체 논리에 따라 확장을 처리합니다.
rm
반면에 와일드카드는 지원하지 않습니다.그 자체로이므로 와일드카드를 인용하려고 하면 rm
대신 파일 이름에서 문자 그대로 별표를 찾도록 지시하게 됩니다.
unzip *.zip
작동하지 않는 이유 는 unzip
의 구문이 단순히 여러 zip 파일을 허용하지 않기 때문입니다. 여러 매개변수가 있는 경우 두 번째 및 후속 매개변수는 아카이브의 파일일 것으로 예상합니다.
unzip [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] 파일[.zip] [파일 ...] [-x x파일 ...] [-d exdir]
답변2
두 명령의 차이점은 인용된 *
문자입니다. 쉘에서 명령을 호출하고 해당 *
문자를 인수로 사용하면 쉘 자체가 인수를 평가합니다. 다음 예를 참조하세요.
$ ls
file1.zip file2.zip file3.zip file4.txt
이제 *
:
$ ls *.zip
file1.zip file2.zip file3.zip
쉘은 와일드카드를 평가하고 다음과 같이 명령을 작성합니다.
$ ls file1.zip file2.zip file3.zip
인용된 와일드카드를 사용하면 문자 그대로 다음과 같은 이름의 파일로 해석됩니다 *.zip
.
$ ls "*".zip
ls: cannot access *.zip: No such file or directory
여러 개의 압축 파일을 인수로 사용하여 유틸리티 unzip
를 호출할 수 없습니다. 하지만 개발자는 이에 대해 다른 방법을 선택했습니다. 맨페이지에서:
파일[.zip]
[...] 와일드카드 표현은 일반적으로 사용되는 Unix 셸(sh, ksh, csh)에서 지원되는 표현과 유사합니다. [...] (운영 체제에 의해 해석되거나 수정될 수 있는 문자는 반드시 인용하십시오., 특히 Unix와 VMS에서는 더욱 그렇습니다.)
답변3
차이점은 쉘 자체가 글로브를 확장하는 첫 번째 경우입니다.
% cd /
% echo *
Applications Library Network System Users Volumes bin cores ...
%
두 번째 경우에는 애플리케이션 자체가 해당 문자를 사용하여 Something™을 수행합니다.
% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...
따옴표가 없으면 쉘은 먼저 glob을 확장하고 해당 쉘 glob이 확장된 대상으로 명령이 실행됩니다.
답변4
zip이 여러 인수를 처리하는 방식 때문에 따옴표가 필요합니다.
rm
: 인수 목록의 모든 파일을 제거합니다.
zip
: 첫 번째 인수에서 파일의 압축을 풉니다. 나머지 인수에서만 파일을 추출합니다.
$ ls *.zip
file1.zip file2.zip file3.zip
$ unzip *.zip
Archive: file1.zip
caution: filename not matched: file2.zip
caution: filename not matched: file3.zip
보시다시피 file1.zip에서 file2.zip과 file3.zip을 찾으려고 시도합니다.
여러 zip 파일을 한 번에 추출할 수 있도록 zip은 glob 자체를 다른 결과로 해석하는 기능을 지원합니다.