Удалить файлы из архива tar

17

У меня есть большой файл, foo.tar.xzкоторый содержит много (скажем, 200000) файлов. Я выяснил, что этот архив содержит несколько (около 5000) файлов, которые мне не нужны. У меня недостаточно места на диске, чтобы распаковать все это на мой диск; Кроме того, я боюсь, что атрибуты / права могут быть потеряны, если я это сделаю. У меня достаточно места для размещения двух копий сжатого архива. Существует ли инструмент для удаления некоторых файлов из архива (с регулярным выражением в имени файла) на лету, то есть без распаковки архива в отдельные файлы?

FUZxxl
источник

Ответы:

15

В GNU tar есть --deleteопция, которая в настоящее время работает и с архивами.

Используйте это так, например:

tar -vf yourArchive.tar --delete your/path/to/delete

Осторожно: он, скорее всего, не будет работать с любым магнитным носителем. Но у tarнего нет проблем с работой в конвейере, поэтому вы можете просто использовать временный tar-файл и перезаписать его этим. Он также не будет работать со сжатыми файлами, поэтому вам нужно будет распаковать файл.

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

Evi1M4chine
источник
1
Он существует, но он не работает с файлами, где произвольный доступ невозможен (например, сжатие архивов), но это мой вариант использования.
FUZxxl
1
Другая проблема заключается в том, что я не могу указать шаблон для удаления. Обратите внимание на мой комментарий от 2013 года, где я уже рассмотрел недостатки gtar --delete.
FUZxxl
4
@FUZxxl -Tработает с --deleteи --wildcardsпозволяет вам использовать шаблоны, а не имена файлов, поэтому создайте временный файл, содержащий шаблоны и их использование unxz < file.tar.xz | tar --wildcards --delete -T patternfile | xz > file2.tar.xz. Он не будет выполнять полное регулярное выражение (если вам это нужно, просто используйте tar -tи создайте список имен файлов для удаления), только шаблоны соответствия файлов.
Random832
14

(отредактировано, поскольку я неправильно понял вопрос, который был также отредактирован)

Лучшее, что вы можете сделать, - это извлечь, удалить и повторно сжать весь файл.

unxz < foobar-old.tar.xz | tar --delete foo/bar | xz > foobar-new.tar.xz

Невозможно удалить файлы из tar напрямую.

деготь представляет собой поток, первоначально предназначенный для ленточных накопителей, которые не делают случайных изыскивает хорошо - хотя теоретически это может быть возможно на диске файловой системы пробивать отверстие / переписать оставшийся файл со сжатием точка является спорным, поскольку большинство, если не все Методы сжатия сильно зависят от содержимого, которое ранее встречалось в файле. Чтобы сделать это на месте, вам понадобятся очень подробные знания как о методе сжатия, так и о формате файла tar. Это сложность до такой степени, что никто бы даже не стал беспокоиться об этом. Дешевле просто хранить файлы и игнорировать их.

Если вам нужна эта функциональность, вероятно, tar - это не то, что вам нужно.

frostschutz
источник
Эти файлы составляют 35% от размера архивов. Ограничения, которые вы указываете, по-видимому, применяются только в том случае, если я переписываю файл, а не если я изменяю его неуместно, что я могу сделать (у меня достаточно места для сохранения упакованного архива дважды). Есть ли такой инструмент?
FUZxxl
Возможно, я неправильно понял ваш вопрос. Если вы все-таки готовы распаковать tar и перепаковать его (просто без фактического создания файлов tarred - то есть прямой передачи tar-tar), это может быть возможно.
frostschutz
Да, я могу это сделать. Просто файлы имеют атрибуты uids / gids /, которые мне нужно сохранить. Кроме того, мне не хватает места на диске, чтобы сохранить распакованное представление. У меня достаточно места для сохранения двух упакованных архивов.
FUZxxl
1
Это не проблема вообще. Если я смогу сделать это за один проход, время не будет слишком долгим. Я не могу представить себе какой-либо формат архива, который бы позволял быстро удалять данные, фактически освобождая хранилище.
FUZxxl
1
--wildcardsпомочь ... Я должен был включить ./в начале шаблона, хотя ...
Герт ван ден Берг
-4

Согласно руководству , вы можете передать список имен файлов, чтобы tarизвлечь их. Например:

$ tar --file archive.tar --list
foo
bar
baz

$ tar --file archive.tar --extract foo
Дон хуан де питон
источник
Я не понимаю, как - экстракт помогает мне. Не могли бы вы уточнить? Помните, что я не могу распаковать архив (или его существенные части) на диск.
FUZxxl
2
Пожалуйста, не просто публикуйте ссылки: это вики - добавьте достаточно контента, чтобы люди не покидали страницу, чтобы понять ваш ответ.
Джейсонвриан