Почему подстановочный символ * так отличается в командах zip и rm?

Почему подстановочный символ * так отличается в командах zip и rm?

Я составил скрипт для выполнения некоторых файловых операций для себя. Я использую оператор wild card, *чтобы применять функции ко всем файлам определенного типа, но есть одна вещь, которую я не понимаю. Я могу unzipвсе файлы в папке, как эта

unzip "*".zip

Однако, чтобы удалить все zip-файлы впоследствии, мне нужно сделать следующее:

rm *.zip

То есть, он не хочет кавычек. С другой стороны, распаковка не работает, если я просто укажу * (выдает предупреждение, что "файлы не были сопоставлены").

Почему это отличается? Мне кажется, что это та же самая операция. Или я неправильно использую wild card?

Знакомство с wild cardв Unix на самом деле не вникают в это, и я не смог найти ничего в 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-файлов; если указано несколько параметров, то ожидается, что второй и последующие будут файлами в архиве:

распаковать [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] файл[.zip] [файл(ы) ...] [-x xfile(s) ...] [-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-файлами в качестве аргументов. Но разработчик выбрал для этого другой способ. Из man-страницы:

файл[.zip]

[...] Групповые выражения аналогичны тем, которые поддерживаются в широко используемых оболочках Unix (sh, ksh, csh) [...] (Обязательно заключайте в кавычки все символы, которые могут быть иным образом интерпретированы или изменены операционной системой., особенно в Unix и VMS.)

решение3

Разница в том, что в первом случае оболочка сама расширяет шар:

% cd /                                                       
% echo *
Applications Library Network System Users Volumes bin cores ...
% 

в то время как во втором случае само приложение выполняет какие-то действия™ с этим буквальным символом:

% cd /
% perl -E 'chdir "/tmp" or die; say for glob($ARGV[0])' "*"
com.apple.launchd.aj4FEhYqm5
...

Если кавычки не указаны, оболочка сначала расширяет глоб, а команда будет выполнена с тем, во что был расширен глоб оболочки.

решение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

как вы можете видеть, он пытается найти file2.zip и file3.zip внутри file1.zip

Чтобы вы могли извлекать несколько zip-файлов одновременно, zip поддерживает интерпретацию glob отдельно, с разным результатом.

Связанный контент