Как НЕ включать родительские каталоги при использовании команды zip?

475
John Doe

Мне необходимо:

  1. Пройдите по каталогу и найдите все подпапки, созданные для> X дней назад
  2. Заархивируйте содержимое этих папок в подпапке и удалите предыдущее содержимое

Пример создания файла с начала:

root_folder: sub-dir (many of these): sub-sub-dir (many of these): content1 (can be file or folder) content2 (can be file or folder) content3 (can be file or folder) 

Пример работы с файлом после завершения команды:

root_folder: sub-dir: sub-sub-dir: zipfile.zip 

НО! Я не хочу включать всю структуру папок (sub-dir / sub-sub-dir) в zip-файл. Я только хочу, чтобы почтовый файл был похож на это:

zip_file: content1 (no matter if it is a file or a folder with content in it) content2 (no matter if it is a file or a folder with content in it) content3 (no matter if it is a file or a folder with content in it) 

Вместо:

zip_file: sub-dir: sub-sub-dir: content1 content2 content3 

Команда, которую я использовал до сих пор, решает все, кроме части структуры папок ... Это выглядит примерно так (сейчас у меня нет точной команды передо мной. Я, вероятно, обновлю ее завтра.

find * -mindepth X -maxdepth X -mtime +10 -exec zip -r -m \{}/zipfilename {} \; 
1

1 ответ на вопрос

0
Possum

I think you want to use -execdir instead of -exec.

From the manpage:

 -execdir command ; -execdir command {} + Like -exec, but the specified command is run from the subdirec‐ tory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids race conditions dur‐ ing resolution of the paths to the matched files. As with the -exec action, the `+' form of -execdir will build a command line to process more than one matched file, but any given invocation of command will only list files that exist in the same subdirec‐ tory. If you use this option, you must ensure that your $PATH environment variable does not reference `.'; otherwise, an attacker can run any commands they like by leaving an appropri‐ ately-named file in a directory in which you will run -execdir. The same applies to having entries in $PATH which are empty or which are not absolute directory names. If find encounters an error, this can sometimes cause an immediate exit, so some pend‐ ing commands may not be run at all. The result of the action depends on whether the + or the ; variant is being used; -execdir command {} + always returns true, while -execdir com‐ mand {} ; returns true only if command returns 0. 

For example:

$ find sub-dir sub-dir sub-dir/sub-sub-dir sub-dir/sub-sub-dir/content3 sub-dir/sub-sub-dir/content1 sub-dir/sub-sub-dir/content1/file sub-dir/sub-sub-dir/content2 $ find sub-dir/ -mindepth 2 -maxdepth 2 -type d -execdir zip -r -m {}/zipped {} \; 

...

$ unzip -l sub-dir/sub-sub-dir/content1/zipped.zip Archive: sub-dir/sub-sub-dir/content1/zipped.zip Length Date Time Name --------- ---------- ----- ---- 0 2017-05-17 17:23 content1/ 4 2017-05-17 17:23 content1/file --------- ------- 4 2 files 

Of course, if you don't want any paths in your zip file, you can just pass -j (or --junk-paths) to store the just the files.

Спасибо, очень, очень, очень, очень! execdir был именно тем, что я хотел. Теперь осталась только одна незначительная проблема ... :) Если я хочу назвать zip-файл более динамичным, например: sub-dir_sub-sub-dir.zip, возможно ли это как-нибудь? Еще раз; огромное спасибо за помощь! Это определенно сэкономило мне время. John Doe 7 лет назад 0
Это начинает усложняться :) Я думаю, что ключом будет передать скрипт с `-execdir` вместо команды. Создав новую оболочку, вы сможете проверить `$ PWD` и управлять ею на основе этого. Например, `-execdir bash -c 'zipname = $ ; zip -r $ zipname ... '`(хотя в IMO проще сделать скрипт, чем использовать` bash -c`). Possum 7 лет назад 0

Похожие вопросы