Как извлечь конкретный файл (ы) из tar.gz

106

Как мы можем извлечь определенные файлы из большого файла tar.gz? В этом вопросе я обнаружил процесс извлечения файлов из tar-файла, но, попробовав там упомянутую команду, я получил ошибку:

$ tar --extract --file={test.tar.gz} {extract11}
tar: {test.tar.gz}: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

Как мне извлечь файл из tar.gz?

Анкит Вашиштха
источник
Обратите внимание, что любое решение должно сначала распаковать весь архив: superuser.com/questions/655739/… Если вы хотите избежать этого, вам нужно будет использовать другой формат, например zip. Однако ZIP обеспечивает меньшее сжатие, поскольку он сжимает отдельный файл отдельно: superuser.com/questions/1013309/… Интересно, существует ли формат, который поддерживает как скорость, так и возможность извлечения одного файла.
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

120

Вы также можете использовать tar -zxvf <tar filename> <file you want to extract>

Вы должны написать имя файла точно так, как tar ztf test.tar.gzэто показано. Если он говорит, например ./extract11, или some/bunch/of/dirs/extract11, это то, что вы должны дать (и файл будет отображаться именно под этим именем, необходимые каталоги создаются автоматически).

  • -x: инструктирует tar для извлечения файлов.
  • -f: указывает имя файла / имя тарбола.
  • -v: Подробный (показать прогресс при извлечении файлов).
  • -z: фильтровать архив через gzip, использовать для распаковки .gz файлов.
harish.venkat
источник
$ tar -zxvf test.tar.gz extract11 tar: extract11: Not found in archive tar: Error exit delayed from previous errors
Анкит Вашиштха,
1
затем попробуйте это. tar tf archive.tar.gz | grep extract11Пожалуйста, проверьте, есть ли extract11 в архиве или нет
harish.venkat
8
Вы должны написать имя файла точно так, как tar ztf test.tar.gzэто показано. Если он говорит, например ./extract11, или some/bunch/of/dirs/extract11, это то, что вы должны дать (и файл будет отображаться именно под этим именем, необходимые каталоги создаются автоматически).
vonbrand
Я хотел бы добавить здесь пункт, -zопция не работает в некоторых версиях Unix, таких как HP-UX.
Анкит Вашиштха
1
@ pj-brunet: Нет, fне должно быть в конце. Но за ним должно следовать имя файла. Этот пример со всеми другими вариантами после имени дегтя работает отлично: tar -f mytar.tar.gz -zxv dir/somefile. Он извлекает "dir / somefile" из "mytar.tar.gz".
mivk
34

Предположим, у вас есть tarball, lotsofdata.tar.gzи вы просто знаете, что там есть один файл, который вы хотите, но все, что вы можете вспомнить, это то, что его имя содержит слово contract. У вас есть два варианта:

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

Опция 1

$ tar -tzf lotsofdata.tar.gz | grep contract

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

$ tar -xzf lotsofdata.tar.gz <full path and filename from your list above>

Вам может понадобиться ./перед вашим путем, чтобы он работал.

Вариант 2

$ tar -xzf lotsofdata.tar.gz --wildcards --no-anchored '*contract*'

До вас, что вы находите проще или наиболее полезным.

Венди Крикс
источник
Убирайся. Опечатка в последней команде: я продублировал -xzf. Должен быть только один экземпляр этих переключателей.
Венди Крикс
tar -xzf lotsofdata.tar.gz <full path and filename from your list above>работал для меня без предоставления ./в начале полного пути
user13107
Возможно, вам придется набраться терпения, заняло некоторое время ... Также, возможно, это очевидно, но он собирается извлечь всю структуру каталогов в текущем каталоге, даже если эти каталоги еще не существуют.
PJ Brunet
BSD tar (по крайней мере, в macOS) не поддерживает эту --wildcardsопцию. Я был в состоянии все еще получить подобное поведение с -x -O *foo. *fooв моем случае это был глобус имени файла, так как я знал, что файл заканчивается на foo.
Эрик Ху,
6

Я пытался извлечь пару сотен файлов из tarball с тысячами файлов на днях. На нужные мне файлы нельзя ссылаться одним подстановочным знаком. Так что я погуглил и нашел эту страницу.

Тем не менее, ни один из вышеперечисленных приемов не подходит для моей задачи. Я закончил тем, что читал человека, и нашел эту опцию --files-from, поэтому мое окончательное решение

gunzip < thousands.tar.gz | tar -x -v --files-from hundreds.list -f -

и это работает как шарм.

Обновление: файл списка должен иметь тот же формат, что и вы tar -tvf, иначе вы не сможете извлечь какие-либо файлы.

Джей Джей Тан
источник
2

Ваш пример работает для меня, если вы опустите скобки

$ tar --extract --file=test.tar.gz extract11

Если ваш файл extract11 находится в подпапке, вы должны указать путь в архиве.

$ tar --extract --file=test.tar.gz subfolder/extract11
Бернхард
источник
$ tar --extract --file=test.tar.gz extract11 tar: extract11: Not found in archive tar: Error exit delayed from previous errors
Анкит Вашиштха,
Тогда obiously extract11 не находится в tar-файле. Убедитесь, что вам нужно указать относительный путь. См редактировать
Бернхард
1

Ниже приведены примеры извлечения определенных файлов из файла tar.gz.

Из локального файла:

$ tar xvf file.tgz path/README.txt 2nd_file.txt

С удаленного URL:

$ curl -s http://example.com/file.tgz | tar xvf - path/README.txt 2nd_file.txt
kenorb
источник