Запилить все файлы в каталоге?

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

Комментарии к вопросу (4)
Решение

Вы можете просто использовать *; нет необходимости в *.*. Расширения файлов не являются специальными в 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; таким образом можно получить документацию по большинству команд.

Комментарии (16)

В моем случае я хотел застегнуть каждый файл в отдельный архив, поэтому я сделал следующее (в zsh):

$ for file in *; do zip ${file%.*}.zip $file; done
Комментарии (3)

Другим способом может быть использование find и xargs: (это может включить каталог "." в zip, но он все равно должен извлечься правильно. В моем тесте zip удалил точку перед сжатием) find . -type f -exec zip zipfile.zip {} +

(+ можно заменить на \;, если ваша версия find не поддерживает окончание + для exec. Однако это будет медленнее...)

По умолчанию это включит все подкаталоги. В GNU find -maxdepth может предотвратить это.

Комментарии (1)

Другой (медленный) способ сделать это (который добавляет один файл в 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 на * (временное решение) и будет запустить молнию один раз для каждого файла, добавив его в архив. В Баш, он будет иметь дело с большим количеством файлов.

Это будет медленнее, чем большинство других методов, но является относительно простым.

Комментарии (4)