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

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

 unzip "*".zip 

Однако, чтобы удалить все почтовые файлы после этого, мне нужно сделать

 rm *.zip 

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

Почему это другое? Для меня это похоже на ту же самую операцию. Или я неправильно использую wild card?

Введение в wild card в Unix на самом деле не затрагивает этого, и я не мог найти что-либо в rm или zip документах.

Я использую терминал на Mac (Yosemite).

5 Solutions collect form web for “Почему символ дикой карты * настолько отличается между командами zip и rm?”

Вы очень хорошо объяснили ситуацию. Последняя часть головоломки заключается в том, что 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 xfile (s) …] [-d exdir]

Разница между этими двумя командами – это символ * . Если вы вызываете команду в оболочке и используете символ * для аргумента, сама оболочка будет оценивать аргумент. См. Этот пример:

 $ 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 нельзя вызывать с несколькими заархивированными файлами в качестве аргументов. Но разработчик выбрал для этого другой путь. С manpage:

файл [.zip]

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

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

 % 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, и команда будет выполняться с тем, что расширяет оболочку оболочки.

Команда будет получать аргументы после их обработки оболочкой.

При первой обработке без кавычек * будет расширяться оболочкой (в список файлов в текущем каталоге (pwd), который соответствует шаблону):

 echo *.zip 

Перечислит все .zip файлы. Но echo "*".zip" не будет.

При первой обработке цитируемый "*" не будет расширяться, он будет передан команде unzip в качестве параметра (после цитирования был удален). Команда unzip получит параметр *.zip :

 $ echo unzip "*".zip unzip *.zip 

Это команда unzip, которая расширяет * список файлов.


Также интересно, что эти две команды не будут выполнять то же самое окончательное действие, и кто расширяет * изменения:

 unzip "*".zip ### the command unzip expands `*.zip`. unzip *.zip ### the shell expands `*.zip`. 

Первая команда получает *.zip который он расширяет для обработки всех файлов. Вторая команда unzip получит список всех .zip файлов в pwd, которые он не будет обрабатывать, поскольку разработчик unzip решил отклонить расширение более чем одного zip файла.

кавычки нужны из-за того, как 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 самостоятельно, с другим результатом.

  • Извлечение вложенных zip-файлов
  • Существуют ли какие-либо утилиты архива, которые могут сохранить атрибут даты, созданный в NTFS-3G?
  • распаковать / распаковать файлы с помощью Curl на ftp-сервере
  • Команда Unix zip обновляет существующий архив, а не создает новый
  • Как я могу игнорировать «zip warning: name not match» при использовании команды zip с опцией -d?
  • Ошибка распаковки, возможно ли восстановление?
  • Что не так с этой командой `zip` для создания многосегментного архива?
  • Текст с круговым отключением через zip, unzip с ошибкой «лишних байтов» в OS X
  • Сжатие старых файлов журнала и переход в новый каталог
  • Объект AIX для ZIP-списка файлов
  • Zip содержимое каталога без самой директории
  • Linux и Unix - лучшая ОС в мире.