Я собрал скрипт, чтобы сделать некоторые файловые операции для меня. Я использую подстановочный оператор *
для применения функций ко всем файлам типа, но есть одна вещь, которую я не понимаю. Я могу unzip
все файлы в папке, как это
unzip "*".zip
Тем не менее, чтобы удалить все почтовые файлы впоследствии, мне нужно сделать
rm *.zip
То есть он не хочет кавычек. Разархивирование, с другой стороны, не работает, если я просто даю ему * (предупреждает, что «файлы не были сопоставлены»).
Почему это отличается? Мне кажется, это точно такая же операция. Или я использую подстановочный знак неправильно?
Знакомство с подстановочным знаком в Unix на самом деле не относится к этому, и я не смог найти что-либо в rm
или zip
документах.
Я использую терминал на Mac (Yosemite).
unzip
мог бы сделать это без обычногоfor f in *.zip;do...done
цикла оболочки. Такой странный не-Unix-подобный интерфейс командной строки.unzip
применяет глобус к содержимому архива; вы не можете получить их из Bash с подстановочным знаком. (Вам нужно `` для f inunzip -l archive.zip
; do ... done`)unzip
что глобусы должны совпадать внутри одного zip-файла. Но это другое; Я на самом деле пыталсяunzip '*.zip'
в каталоге с несколькими файлами ZIP, и он извлекает все файлы из всех ZIP. Как я уже сказал, супер странно.tar
не имеет никакого режима работы, подобного этому.Ответы:
Вы очень хорошо объяснили ситуацию. Последняя часть головоломки состоит в том, что она
unzip
может обрабатывать символы подстановки сама:http://www.info-zip.org/mans/unzip.html
Процитировав подстановочный знак *, вы запретили расширению своей оболочки, чтобы он
unzip
видел подстановочный знак и имел дело с расширением в соответствии с его собственной логикой.rm
, Напротив, не поддерживает подстановочные знаки на своем собственном , поэтому попытку процитировать подстановочный будет инструктироватьrm
искать буквальную звездочку в имени файла вместо этого.Причина, по которой
unzip *.zip
это не работает, заключается в том, чтоunzip
синтаксис просто не позволяет использовать несколько zip-файлов; если имеется несколько параметров, ожидается, что 2-й и последующие параметры будут файлами в архиве:источник
unzip
на своем родном языке, в другом - на общем Unix Lingo?for f in *.zip ; do unzip -v "$f" ; done
. и большая часть причины, почему оболочка выполняет расширение имени файла и т. д. сама по себе такова, что каждая отдельная программа не обязана (что привело бы к множеству независимо написанных реализаций расширения с подстановочными знаками, которые отличались небольшими, но раздражающими способами) ,Разница между этими двумя командами заключается в кавычках
*
. Если вы вызываете команду в оболочке и используете*
символ для аргумента, оболочка сама оценит аргумент. Смотрите этот пример:Теперь с
*
:Оболочка оценивает подстановочный знак и создает команду следующим образом:
С цитируемым подстановочным знаком он интерпретируется как файл с именем (буквально)
*.zip
:unzip
Утилита не может быть вызван несколькими сжатых файлов в качестве аргументов. Но разработчик выбрал другой путь для этого. Из справочной страницы:источник
unzip
решили пойти по этому пути, а не использовать несколько сжатых файлов в качестве аргументов?Разница в том, что в первом случае оболочка сама расширяет глобус:
в то время как во втором случае само приложение делает что-то ™ с этим буквенным символом:
Если не заключено в кавычки, оболочка сначала расширяет глоб, и команда будет выполняться с любым расширением глобуса оболочки.
источник
Команда получит аргументы после того, как они были обработаны оболочкой.
При первой обработке не заключенные в кавычки
*
будут расширяться оболочкой (до списка файлов в текущем каталоге (pwd), которые соответствуют шаблону):Перечислю все
.zip
файлы. Но неecho "*".zip"
буду .При первой обработке кавычка
"*"
не будет расширена, она будет передана команде unzip в качестве параметра (после удаления кавычек). Команда unzip получит параметр*.zip
:Это команда unzip, которая расширяет
*
список файлов.Также интересно, что эти две команды не будут выполнять одно и то же окончательное действие, и кто расширяет
*
изменения:Первая команда получает
*.zip
расширение, которое обрабатывает все файлы. Вторая командаunzip
получит список всех.zip
файлов в pwd, которые она не будет обрабатывать, так как разработчик unzip решил отклонить расширение более чем одногоzip
файла.источник
Кавычки необходимы из-за способа, которым zip обрабатывает несколько аргументов:
rm
: удалить все файлы в списке аргументовzip
: разархивировать файл в первом аргументе. только извлекать файлы в оставшихся аргументах.как вы видите, он пытается найти file2.zip и file3.zip внутри file1.zip
чтобы вы могли извлекать сразу несколько zip-файлов, zip поддерживает интерпретацию глобуса самостоятельно, что дает другой результат.
источник