Перетворіть контури архіву tar, не вилучаючи його


10

У GNU tar(1)є акуратний варіант, який називається --transform. На чоловіковій сторінці:

--transform, --xform EXPRESSION
використовувати sed замінити EXPRESSION для перетворення імен файлів

Це дозволяє перетворювати назви шляхів на льоту під час вилучення архіву, щоб ви могли контролювати, де і як він буде видобутий.

Моє запитання, чи є спосіб здійснити подібну трансформацію in situ ; тобто не витягуючи архів?

Приклад

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

Використовуйте футляр

Я поширюю tarархів в основному безглуздих кінцевих користувачів і хотів би, щоб він вийшов у правильний шлях без втручання від мене. Я намагаюся уникати тривіального рішення про вилучення архіву, перейменування каталогів та перепакування, оскільки архів є великим.


Чому ви не трансформуєте імена під час створення?
Хосе Луїс Мартін

@JoseLuisMartin Справа. Мій випадок використання полягає в тому, що архів вже є, і, як я вже сказав, я хотів би уникнути розпакування, перетворення та перепакування.
Йосип Р.

1
Ви можете змінити потік смоли, не фактично витягаючи його на диск: github.com/mafintosh/tar-stream#modifying-existing-tarballs , perldoc.perl.org/5.10.1/Archive/Tar.html тощо
vladr

Відповіді:


3

Ви можете змонтувати архів з архівом-вантажем або mounttavfs і відтворити його знову

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

Операції запису в архівній файловій системі дозволять виконати повне перезаписування на umount, тому не здайтеся хорошим варіантом для великих файлів.

EDIT

Я не знаю деталей реалізації, але, здається, ми зберігаємо файли запису до кроку файлової системи.

Просто тест на вирішення чуваків (над дьогтем мого / usr)

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

Вихід:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

Тож Авфс перемагає! .


1
+1 Цікава нова команда. Але чим цей підхід відрізняється від розпакування архіву? Я кажу не про реалізацію, а про ефективність.
Джозеф Р.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.