Как удалить файлы определенных типов во всех подкаталогах?

86

Я хочу использовать tar и все файлы .php и .html в каталоге и его подкаталогах. Если я использую

tar -cf my_archive *

он сортирует все файлы, которые мне не нужны. Если я использую

tar -cf my_archive *.php *.html

он игнорирует подкаталоги. Как я могу сделать его рекурсивным, но включать только два типа файлов?

user1566515
источник

Ответы:

146

find ./someDir -name "*.php" -o -name "*.html" | tar -cf my_archive -T -

DeeDee
источник
@DeeDee Есть ли ограничения на количество файлов и т. Д.?
user1566515
1
@DeeDee - нет, я имел в виду, что тебе не нужны паренсы!
Майк Макуч
@ user1566515 Может быть какое-то ограничение файловой системы или общий предел пространства, который ставит верхний предел для вашего tar-файла. Это полностью зависит от вашей собственной системы. В противном случае конвейер будет фактически создавать tar-файл на лету, поэтому вы не будете ограничены номером или размером файла.
DeeDee
Благодаря! ... как добавить более двух условий / типов файлов?
gluuke
5
@gluuke use -o -name [pattern]для каждого нового состояния
DeeDee
15

Если вы используете bashверсию> 4.0, вы можете использовать эксплойт, shopt -s globstarчтобы быстро с этим справиться:

shopt -s globstar; tar -czvf deploy.tar.gz **/Alice*.yml **/Bob*.json

это добавит все файлы .yml, которые начинаются с Алисы, из любого подкаталога и добавит все файлы .json, которые начинаются с Боба, из любого подкаталога.

Сайрам Криш
источник
2
Единственный ответ, который просто использует tar, лучший ответ IMO.
симон
2
Несмотря на впечатление от glob '**' для каталога, эта команда не выполняется рекурсивно (любые подпапки)
Эдди
@Eddie ** должен работать. может быть что то другое с вашими параметрами. Также проверьте, есть ли пробел в имени папки, которое вы передаете в командной строке. Если нет, можете ли вы вставить свою настоящую команду?
Сайрам Криш
'**' оценивается оболочкой перед достижением команды и рассматривается только как 2 независимых *, которые разрешаются до 0 или символов, у него нет рекурсивной функции для охвата каталогов tldp.org/LDP/GNU-Linux-Tools-Summary/ html / x11655.htm
Эдди,
2
@eddie да, он оценивается оболочкой, хотя у bash> 4.0 есть shopt -s globstarопция, поэтому ответ правильный и на самом деле лучший
Роман Ушеренко 02
13

Один из способов:

tar -cf my_archive.tar $( find -name "*.php" -or -name "*.html" )

Однако при использовании этого метода есть некоторые предостережения:

  1. Он не удастся, если есть какие-либо файлы или каталоги с пробелами в них, и
  2. он потерпит неудачу, если файлов так много, что максимальная длина командной строки заполнена.

Обходной путь для них может заключаться в том, чтобы вывести содержимое команды find в файл, а затем использовать параметр «-T, --files-from FILE» для tar.

Робин Шит
источник
1) Под "неудачей" вы имеете в виду, что файлы с пробелами будут пропущены или tar-архив не будет создан? 2) У меня около 100К файлов. Это превышает максимальную длину командной строки?
user1566515
1
1. Он создаст архив, но сообщит об отсутствии файлов. 2. Полагаю, это будет слишком долго. Учитывая это, вам лучше всего использовать метод, подобный тому, который предлагает @DeeDee ниже, он отлично справится с этими проблемами.
Робин Шит
4

Это будет обрабатывать пути с пробелами:

find ./ -type f -name "*.php" -o -name "*.html" -exec tar uvf myarchives.tar {} +
Ян Рейнхарт Гейзер
источник
0

Поместите их в файл

find . \( -name "*.php" -o -name "*.html" \) -print > files.txt

Затем используйте файл в качестве входных данных для tar, используйте -I или -T в зависимости от версии tar, которую вы используете

Используйте h для копирования символических ссылок

tar cfh my.tar -I files.txt 
Ноам Геффен
источник
0

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -I 'pigz -9' -cf target.tgz

для многоядерности или только для одного ядра:

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -czf target.tgz

dmitry_podyachev
источник
-2
tar -cf my_archive `find ./ | grep '.php\|.html'`

Используйте команды «find» и «grep», чтобы получить весь путь к файлам .php и .html во всех каталогах и их подкаталогах. Затем передайте информацию о пути в tar для сжатия.

Будьте осторожны с символом "и". Также обратите внимание, что это приведет к достижению предела того, сколько символов ваша оболочка разрешит в командной строке, в отличие от некоторых других ответов.

Трент Хуанг
источник