Команда Shell для каталога tar, исключая определенные файлы/папки

Существует ли простая команда/скрипт оболочки, которая поддерживает исключение определенных файлов/папок из архива?

У меня есть каталог, который нужно заархивировать с подкаталогом, содержащим несколько очень больших файлов, которые мне не нужно резервировать.

Не совсем решения:

Команда tar --exclude=PATTERN соответствует заданному шаблону и исключает эти файлы, но мне нужно игнорировать определенные файлы и папки (полный путь к файлу), в противном случае допустимые файлы могут быть исключены.

Я также мог бы использовать команду find, чтобы создать список файлов и исключить те, которые я не хочу архивировать, и передать список в tar, но это работает только с небольшим количеством файлов. У меня десятки тысяч.

Я начинаю думать, что единственное решение - создать файл со списком исключаемых файлов/папок, затем использовать rsync с --exclude-from=file для копирования всех файлов в каталог tmp, а затем использовать tar заархивировать этот каталог.

Кто-нибудь может придумать лучшее/более эффективное решение?

РЕДАКТИРОВАТЬ: Чарльз Ма решение работает хорошо. Большая проблема в том, что --exclude='./folder' ДОЛЖЕН быть в начале команды tar. Полная команда (сначала cd, поэтому резервное копирование относится к этому каталогу):

cd /folder_to_backup
tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

Ответ 1

У вас может быть несколько вариантов исключения для tar, поэтому

$ tar --exclude='./folder' --exclude='./upload/folder2' -zcvf /backup/filename.tgz .

и т.д. будет работать. Сделайте уверенным, чтобы поставить --exclude до исходные и целевые элементы.

Ответ 2

Вы можете исключить каталоги с --exclude для tar.

Если вы хотите архивировать все, кроме /usr, вы можете использовать:

tar -zcvf /all.tgz / --exclude=/usr

В вашем случае возможно что-то вроде

tar -zcvf archive.tgz arc_dir --exclude=dir/ignore_this_dir

Ответ 3

Возможные варианты исключения файлов/каталогов из резервной копии с помощью tar:

Исключить файлы с помощью нескольких шаблонов

tar -czf backup.tar.gz --exclude=PATTERN1 --exclude=PATTERN2 ... /path/to/backup

Исключить файлы, используя файл exclude, заполненный списком шаблонов

tar -czf backup.tar.gz -X /path/to/exclude.txt /path/to/backup

Исключить файлы с помощью тегов, поместив файл тега в любую директорию, которая должна быть пропущена

tar -czf backup.tar.gz --exclude-tag-all=exclude.tag /path/to/backup

Ответ 4

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

если у вас есть следующая структура

/home/ftp/mysite/

со следующими файлами/папками

/home/ftp/mysite/file1
/home/ftp/mysite/file2
/home/ftp/mysite/file3
/home/ftp/mysite/folder1
/home/ftp/mysite/folder2
/home/ftp/mysite/folder3

поэтому вы хотите создать tar файл, содержащий все внутри /home/ftp/mysite (чтобы переместить сайт на новый сервер), но file3 является просто мусором, а все в folder3 также не является необходимо, поэтому мы пропустим эти два.

мы используем формат

tar -czvf <name of tar file> <what to tar> <any excludes>

где c = create, z = zip и v = verbose (вы можете видеть файлы по мере их ввода, полезно, чтобы убедиться, что ни один из файлов, которые вы исключаете, добавляется). и f = файл.

поэтому моя команда будет выглядеть так:

cd /home/ftp/
tar -czvf mysite.tar.gz mysite --exclude='file3' --exclude='folder3'

обратите внимание, что файлы/папки исключены относительно корня вашего tar (я пробовал полный путь здесь относительно /, но я не могу сделать эту работу).

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

Ответ 5

Вы можете использовать стандартную нотацию ant, чтобы исключить относительные каталоги.
Это работает для меня и исключает каталоги .git или node_module.

tar -cvf myFile.tar --exclude=**/.git/* --exclude=**/node_modules/*  -T /data/txt/myInputFile.txt 2> /data/txt/myTarLogFile.txt

myInputFile.txt Содержит:

/DEV 2/Java
/DEV 2/JavaScript

Ответ 6

Я испытал это, по крайней мере, с помощью версии Cygwin tar, которую я использую ( "CYGWIN_NT-5.1 1.7.17 (0.262/5/3) 2012-10-19 14:39 i686 Cygwin" в Windows XP Home Edition SP3), порядок опций важен.

Пока эта конструкция работала для меня:

tar cfvz target.tgz --exclude='<dir1>' --exclude='<dir2>' target_dir

что один не работает:

tar cfvz --exclude='<dir1>' --exclude='<dir2>' target.tgz target_dir

Это, пока tar --help показывает следующее:

tar [OPTION...] [FILE]

Итак, вторая команда также должна работать, но, по-видимому, это не так...

Лучшие rgds,

Ответ 7

Этот шаблон exclude обрабатывает суффикс имени файла, например png или mp3, а также имена каталогов, такие как .git и node_modules

tar --exclude={*.png,*.mp3,*.wav,.git,node_modules} -Jcf ${target_tarball}  ${source_dirname}

Ответ 8

Я нашел это где-то в другом месте, поэтому я не буду брать кредит, но он работал лучше, чем любое из вышеперечисленных решений для моих конкретных проблем (даже если это закрыто):

tar zc --exclude __MACOSX --exclude .DS_Store -f <archive> <source(s)>

Ответ 9

Для тех, у кого есть проблемы с этим, некоторые версии tar будут работать только без "./" в значении исключения.

Tar --version

tar (GNU tar) 1.27.1

Синтаксис команды, который работает:

tar -czvf ../allfiles-butsome.tar.gz * --exclude=acme/foo

Они не будут работать:

$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=./acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='./acme/foo'
$ tar --exclude=./acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='./acme/foo' -czvf ../allfiles-butsome.tar.gz *
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude=/full/path/acme/foo
$ tar -czvf ../allfiles-butsome.tar.gz * --exclude='/full/path/acme/foo'
$ tar --exclude=/full/path/acme/foo -czvf ../allfiles-butsome.tar.gz *
$ tar --exclude='/full/path/acme/foo' -czvf ../allfiles-butsome.tar.gz *

Ответ 10

Для Mac OSX мне пришлось делать

tar -zcv --exclude='folder' -f theOutputTarFile.tar folderToTar

Обратите внимание на -f после --exclude=

Ответ 11

Я согласен, что флаг -exclude - правильный подход.

$ tar --exclude='./folder_or_file' --exclude='file_pattern' --exclude='fileA'

Слово предупреждения для побочного эффекта, которое я не нашел сразу очевидным: Исключение "fileA" в этом примере будет искать "fileA" RECURSIVELY!

Пример. Каталог с одним подкаталогом, содержащим файл с таким же именем (data.txt)

data.txt
config.txt
--+dirA
  |  data.txt
  |  config.docx
  • При использовании --exclude='data.txt' архив не будет содержать файл EITHER data.txt. Это может привести к неожиданным результатам при архивировании сторонних библиотек, таких как каталог node_modules.

  • Чтобы избежать этой проблемы, обязательно укажите весь путь, например --exclude='./dirA/data.txt'

Ответ 12

Чтобы избежать возможных ошибок 'xargs: Argument list too long' из-за использования find ... | xargs ... при обработке десятков тысяч файлов, вы можете напрямую передать вывод find на tar с помощью find ... -print0 | tar --null ....

# archive a given directory, but exclude various files & directories 
# specified by their full file paths
find "$(pwd -P)" -type d \( -path '/path/to/dir1' -or -path '/path/to/dir2' \) -prune \
   -or -not \( -path '/path/to/file1' -or -path '/path/to/file2' \) -print0 | 
   gnutar --null --no-recursion -czf archive.tar.gz --files-from -
   #bsdtar --null -n -czf archive.tar.gz -T -

Ответ 13

Прочитав этот поток, я немного тестировал RHEL 5, и вот мои результаты для разгрузки каталога abc:

Это исключает ошибки каталогов и журналы и все файлы в каталогах:

tar cvpzf abc.tgz abc/ --exclude='abc/error' --exclude='abc/logs'

Добавление подстановочного знака после исключенного каталога исключает файлы, но сохраняет каталоги:

tar cvpzf abc.tgz abc/ --exclude='abc/error/*' --exclude='abc/logs/*'

Ответ 14

Используйте команду find в сочетании с параметром tar append (-r). Таким образом, вы можете добавлять файлы в существующий tar за один шаг, вместо двухпроходного решения (создать список файлов, создать tar).

find /dir/dir -prune ... -o etc etc.... -exec tar rvf ~/tarfile.tar {} \;

Ответ 15

Вы также можете использовать один из параметров "-exclude-tag" в зависимости от ваших потребностей:

  • - исключить тег = FILE
  • - исключить тег-все = FILE
  • - исключить тег-под = FILE

Папка с указанным FILE будет исключена.

Ответ 16

Вы можете использовать cpio (1) для создания файлов tar. cpio берет файлы для архивации на stdin, поэтому, если вы уже определили команду find, которую хотите использовать для выбора файлов в архиве, подключите его к cpio для создания файла tar:

find ... | cpio -o -H ustar | gzip -c > archive.tar.gz

Ответ 17

gnu tar v 1.26 --exclude должно появиться после архивного файла и аргументов каталога резервного копирования, не должно иметь никаких ведущих или завершающих косых черт и не предпочитает кавычек (одиночный или двойной). Таким образом, для резервной копии каталога PARENT это:

tar cvfz /path_to/mytar.tgz ./dir_to_backup --exclude=some_path/to_exclude

Ответ 18

Лучше всего использовать find с tar, через xargs (для обработки большого количества аргументов). Например:

find / -print0 | xargs -0 tar cjf tarfile.tar.bz2

Ответ 19

tar -cvzf destination_folder source_folder -X /home/folder/excludes.txt

-X указывает файл, который содержит список имен файлов, которые должны быть исключены из резервной копии. Для экземпляра вы можете указать * ~ в этом файле, чтобы не включать имена файлов, заканчивающиеся на ~ в резервной копии.

Ответ 20

Прочитав все эти хорошие ответы для разных версий и решив проблему для себя, я думаю, что есть очень мелкие детали, которые очень важны и редки для общего использования GNU/Linux, которые недостаточно подчеркнуты и заслуживают большего, чем комментарии.

Поэтому я не буду пытаться ответить на вопрос для каждого случая, а вместо этого попытаюсь зарегистрироваться, где искать, когда что-то не работает.

ЭТО ОЧЕНЬ ВАЖНО ДЛЯ УВЕДОМЛЕНИЯ:

  1. ПОРЯДОК ВАРИАНТОВ ВАРИАНТОВ: это не то же самое, что поставить --exclude до, чем после опции файла и каталогов для резервного копирования. По крайней мере, для меня это неожиданно, потому что, по моему опыту, в командах GNU/Linux порядок опций не имеет значения.
  2. В разных версиях tar эти параметры ожидаются в разном порядке: например, ответ @Andrew указывает, что в GNU tar v 1.26 и 1.28 исключения происходят последними, тогда как в моем случае с GNU tar 1.29 - наоборот.
  3. ТРЕЙЛИНГ РЕЗУЛЬТАТОВ имеет значение: по крайней мере, в GNU tar 1.29 его не должно быть.

В моем случае для GNU tar 1.29 на Debian stretch сработала команда

tar --exclude="/home/user/.config/chromium" --exclude="/home/user/.cache" -cf file.tar  /dir1/ /home/ /dir3/

Цитаты не имели значения, они работали с ними или без них.

Надеюсь это кому-нибудь пригодится.

Ответ 21

Возможный избыточный ответ, но так как я нашел его полезным, вот он:

В то время как root FreeBSD (т.е. использование csh), я хотел скопировать всю свою корневую файловую систему в /mnt, но без /usr и (очевидно)/mnt. Это то, что сработало (я нахожусь в /):

tar --exclude ./usr --exclude ./mnt --create --file - . (cd /mnt && tar xvd -)

Все дело в том, что было необходимо (поместив ./), чтобы указать tar, что исключенные каталоги, где копируется часть большего каталога.

My € 0.02

Ответ 22

Мне не повезло получить tar, чтобы исключить подкаталог 5 Gigabyte на несколько уровней. В конце концов, я просто использовал команду unix Zip. Мне было намного легче.

Итак, для этого конкретного примера из исходного сообщения
(tar --exclude = './folder' --exclude = './upload/folder2' -zcvf/backup/filename.tgz.)

Эквивалент:

zip -r/backup/filename.zip. -x upload/folder/**\* upload/folder2/**\*

(ПРИМЕЧАНИЕ. Вот сообщение, которое я первоначально использовал, что помогло мне https://superuser.com/questions/312301/unix-zip-directory-but-excluded-specific-subdirectories-and-everything-within-t)

Ответ 23

Проверьте

tar cvpzf zip_folder.tgz . --exclude=./public --exclude=./tmp --exclude=./log --exclude=fileName

Ответ 24

Следующий bash script должен сделать трюк. Он использует ответ, указанный здесь Маркусом Сундманом.

#!/bin/bash

echo -n "Please enter the name of the tar file you wish to create with out extension "
read nam

echo -n "Please enter the path to the directories to tar "
read pathin

echo tar -czvf $nam.tar.gz
excludes=`find $pathin -iname "*.CC" -exec echo "--exclude \'{}\'" \;|xargs`
echo $pathin

echo tar -czvf $nam.tar.gz $excludes $pathin

Это выведет нужную команду, и вы можете просто скопировать и вставить ее обратно. Возможно, более элегантный способ предоставить ее непосредственно в командной строке.

Просто измените *.CC на любое другое общее расширение, имя файла или регулярное выражение, которое вы хотите исключить, и это все равно должно работать.

ИЗМЕНИТЬ

Просто добавьте небольшое объяснение; find генерирует список файлов, соответствующих выбранному регулярному выражению (в данном случае *.CC). Этот список передается через xargs в команду echo. Это печатает --exclude "одна запись из списка". Сляки() являются символами escape для "меток".