tar - извлечь отбрасывающую структуру каталогов


34

unzipимеет отличный вариант -j, при котором структура каталогов архива отбрасывается, и все файлы извлекаются в один и тот же каталог.

Есть ли способ заставить tarработать таким же образом? Ничто в справочной странице, кажется, не указывает на это.

Итак, есть ли альтернатива, предпочтительно свободное программное обеспечение, инструмент, который сделает это?


Ответы:


79

GNU tar живет от фуритурита, поэтому, естественно, также есть несколько вариантов для этого.
http://www.gnu.org/software/tar/manual/html_node/transform.html

Если вы просто хотите удалить несколько сегментов пути, то --strip-components=nили --strip=nчасто будете делать:

 tar xvzf tgz --strip=1

Но также возможно переписать и перезаписать файлы, которые будут извлечены (флаги есть --transformили --xformпринимают ereg с /xмодификатором):

 tar xvzf tgz --xform='s#^[^/]+#.#x'
                 # or 's#^.+/##x' for discarding all paths

Для перечисления tar вам нужна дополнительная --show-transformedопция:

 tar tvzf tgz --show-transformed --strip=1 --xform='s/abc/xyz/x'

Я считаю, что варианты перезаписи также работают для упаковки, а не только для извлечения. Но paxимеет явно более приятный синтаксис.


4
Почему нет s#.*/##?
10

3
- полоска только что сделала мой день. Благодарность!
SamStephens

--stripне упоминается на странице руководства os x tar, но все равно работает, спасибо!
slf

3
Гораздо лучше, чем принятый ответ.
Клаату фон Шлакер

есть ли разница между --stripи --strip-components?
Джоэл Беркли

13

Вы можете сделать это довольно легко в два этапа. При необходимости адаптируйте:

$ mkdir /tmp/dirtree
$ tar xfz /path/to/archive -C /tmp/dirtree
$ find /tmp/dirtree -type f -exec mv -i {} . \;
$ rm -rf /tmp/dirtree

Вот как я бы это сделал (используя find -exec mv -iвместо find | xargs) .... простые шаги, которые я могу повторить в любой системе без необходимости носить с собой сценарий, чтобы сделать это для меня.
Квик-кихот

1
+1, tmpdir=$( mktemp -d )удобно при создании временных каталогов
sorki

8

pax может это сделать:

pax -v -r -s '/.*\///p' < archive.tar

или

zcat archive.tar.gz | pax -v -r -s '/.*\///p'

Вы можете сначала проверить операцию замены имени, опуская -rопцию.


1

Возможное решение, которое не требует установки чего-либо.

  1. используйте, tar tvfчтобы получить все файлы из архива
  2. Извлеките эти файлы по отдельности - распакуйте tar в stdout и перенаправьте в $ filename

    tar -tvf $1 | grep -v "^d" | \
                  awk '{for(i=6;i<NF+1;i++) {printf "%s ",$i};print ""}' |\
                  while read filename
                  do
                     tar -O -xf $1 "$filename" > `basename "$filename"`
                  done
    

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


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

Исправлено, но это не так красиво, как было.
DaveParillo

-1
tar xf foo.tar.gz foo/path/to/file/bar.mp3 -O > bar.mp3

-OОпция извлекает файл на стандартный вывод, и >переадресовывает этот вывод в файл. Так что в моем примере я извлекаю foo.mp3 и перенаправляю его в bar.mp3. Имена файлов произвольны.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.