Есть ли способ заархивировать все файлы в заданном каталоге с помощью команды zip
? Я слышал об использовании *.*
, но я хочу, чтобы это работало и для файлов без расширений.
Вы можете просто использовать *
; нет необходимости в *.*
. Расширения файлов не являются специальными в Unix. *
соответствует нулю или более символов, включая точку. Таким образом, он соответствует foo.png
, потому что это ноль или более символов (семь, если быть точным).
Обратите внимание, что *
по умолчанию не ищет файлы, начинающиеся с точки (как и *.*
). Часто это то, что вам нужно. Если нет, то в bash, если вы shopt -s dotglob
, он будет соответствовать (но все равно будет исключать .
и ..
). Другие оболочки имеют другие способы (или вообще не имеют их) включения dotfiles.
В качестве альтернативы, zip
также имеет опцию -r
(рекурсивный), чтобы делать целые деревья каталогов за один раз (и не беспокоиться о проблеме дотфайлов):
zip -r myfiles.zip mydir
где mydir
- это каталог, содержащий ваши файлы. Обратите внимание, что созданный zip будет содержать структуру каталогов, а также файлы. Как указывает peterph в своем комментарии, это обычно рассматривается как хорошая вещь: при извлечении zip все извлеченные файлы будут аккуратно храниться в одном подкаталоге.
Вы также можете указать zip не хранить пути с помощью опции -j
/--junk-paths
.
Команда zip
поставляется с документацией, рассказывающей обо всех ее (многих) опциях; введите man zip
, чтобы посмотреть эту документацию. Это относится не только к zip; таким образом можно получить документацию по большинству команд.
В моем случае я хотел застегнуть каждый файл в отдельный архив, поэтому я сделал следующее (в zsh
):
$ for file in *; do zip ${file%.*}.zip $file; done
Другим способом может быть использование find и xargs: (это может включить каталог "." в zip, но он все равно должен извлечься правильно. В моем тесте zip удалил точку перед сжатием)
find . -type f -exec zip zipfile.zip {} +
(+
можно заменить на \;
, если ваша версия find
не поддерживает окончание +
для exec. Однако это будет медленнее...)
По умолчанию это включит все подкаталоги. В GNU find -maxdepth
может предотвратить это.
Другой (медленный) способ сделать это (который добавляет один файл в zip на время):
for f in * .[^.]*; do
[ -r "$f" ] || continue # Skip directories or non-existant files (Probably ".[^.]*" if directory has no dotfiles). Using -e will allow directories to be used as well
zip zipfile.zip "$f" # If directories are included, you probably want to add -r
done
Это вопросы dotfile на *
(временное решение) и будет запустить молнию один раз для каждого файла, добавив его в архив. В Баш
, он будет иметь дело с большим количеством файлов.
Это будет медленнее, чем большинство других методов, но является относительно простым.