2014-09-03 2 views
0

Мой нижеприведенный код должен искать рекурсивные папки, содержащие файлы doc/docx и архивировать только те, которые находятся на их пути. Когда найти в tar дает пустое. tar разбивается, когда Трусливый отказывается создавать пустой архив. Я использую -maxdepth 1, чтобы избежать этого, но не уверен, что это правильное решение. Другая проблема заключается в том, что обработка не работает должным образом. Если notest существует, тогда тест будет проигнорирован. Какие-либо предложения? чувствовать себя также свободно предложить некоторые оптимизации кодаtar и рекурсивное архивирование

for D in $(find . ! -newermt $date1 -ipath "*test*" -or -ipath "*notest*" -iregex ".*\.\(doc\|docx\)" -printf "%h\n" | sort -u) 
    do : 
    cd $D && tar --no-recursion --ignore-failed-read -czf archive.tar.zip $(find . -maxdepth 1 -iname "*.doc" -or -iname "*.docx") --remove-files 
    cd ~ 
done 

Пример

Test 
    |____ test 
    |  |___ subtest ___ 1.doc 
    |     |___ 2.doc 
    |     |___ 3.pdf 
    |____ notest ___ 1.doc 
       |___ 2.docx 

Ожидаемое

Test 
    |___ test 
    |  |___ subtest ___ archive.tar.zip (contains docs) 
    |     |___ 3.pdf 
    |___ notest ___ archive.tar.zip (contains docs) 
+0

Обратите внимание, что '.zip' указывает конкретный тип архива, который вы можете манипулировать с [зип] (HTTP: // WWW. freebsd.org/cgi/man.cgi?query=zip&manpath=FreeBSD+Ports+9.2-RELEASE) и [unzip] (http://www.freebsd.org/cgi/man.cgi?query=unzip&manpath=FreeBSD+Ports + 9.2-RELEASE). Для gzipped tar обычно принято завершать имя файла в '.tar.gz'. – ghoti

+0

Это идея, потому что это облачное хранилище и может открываться различными станциями, работающими под управлением ОС. Поэтому не нужно ограничивать пользователей инструментами. – Odin

+0

Изменение имени файла не изменяет формат файла. Если вы хотите создать zip-архив, вы должны использовать инструмент, который может это сделать. Тар, вероятно, не тот инструмент. Если вы хотите что-то, что работает одинаково для почти всех unix-подобных систем, скорее всего, путь .tar.gz. Если вам нужна совместимость с Windows, ZIP может быть лучшим вариантом. В любом случае, вам нужен правильный инструмент для работы. – ghoti

ответ

1

Попробуйте следующие:

arch="archive.tar.gz" 
while read -r -d $'\0' dir 
do 
    (cd "$dir" && find . -maxdepth 1 -iregex '.*\.docx?' -print0 | tar --null -czf "$arch" -T - --remove-files) 
    #alternatively 
    #(cd "$dir" && shopt -s nocaseglob nullglob && tar --no-recursion -czf "$arch" *.doc *.docx --remove-files) 
done < <(find . \(-ipath '*/test/*' -o -ipath '*/notest/*' \) -iregex '.*\.docx?' -printf '%h\0' | sort -zu) 

некоторые комментарии:

  • альтернатива -ipath со строительством \(-ipath '*/test/*' -o -ipath '*/notest/*' \)
  • регулярного выражения .*\.docx? - должен соответствовать всему имени файла и x? означают ноль или один x
  • деготь может прочитать список файлов из стандартного ввода с -T -
  • с использованием нулевых имен файлов (помогает, если пути содержат пробелы)
  • --null инструктирует tar использовать su ч нулем имена файлов
  • (cd ... &&) запустить в субоболочке, так что не нужно cd назад
+0

Я использовал частично то, что вы предложили, и дал лучшие результаты. Thanks – Odin

+0

@Odin не проблема. В любом случае, для меня я дал именно то, что вы хотели - если у вас есть какие-то проблемы, отредактируйте свой вопрос ... – jm666

+0

Как я могу использовать '-iregex' с' -ipath'. Например, '\ (-ipath -iregex". * \. \ (Test \ | notest \) \) "'? – Odin

Смежные вопросы