Як вибрати ім'я каталогу під час видалення


124

Скажіть, у мене є ім'я файлу ugly_name.tar, який після вилучення стає ugly_nameкаталогом. Яку команду я можу використовувати таку, що отримане ім’я каталогу pretty_nameзамість цього?

Відповіді:


171

Це має працювати:

mkdir pretty_name && tar xf ugly_name.tar -C pretty_name --strip-components 1

-Cзміни у вказаному каталозі перед розпакуванням (або упаковкою). --strip-componentsвидаляє зазначену кількість каталогів з імен файлів, що зберігаються в архіві.

Зауважте, що це насправді не портативний. GNU tar та, принаймні, деякі BSD-тари мають --strip-componentsможливість, але, схоже, вони не існують на інших платформах, подібних unix.

Німий спосіб зробити це буде працювати майже скрізь, хоча.

tar xf ugly_name.tar && mv ugly_name pretty_name

Я думаю, я буду дотримуватися німої версії :)
phunehehe

28
@phunehehe: однією з переваг смарт-версії є те, що ви не повинні заздалегідь знати, що таке незіркована назва каталогу
tshepang

2
Можна додати, що це працює більше, ніж "Pretty_name". Ви також можете скасувати видалення до певного каталогу. Приклад:tar -xvf /tmp/backupfiles.tar -C /var/www/
Генерал Реднек

2
Я зазвичай використовую тупий спосіб, і я використовую підстановку на випадок, якщо я не знаю, яке потворне ім’я буде або я не хочу його записувати. mv ugly-* pretty_name
Девід Грейсон

1
Німий спосіб не працює, якщо вже є ugly_nameкаталог. До речі, краса в очах глядача.
kmiklas

30

За допомогою GNU tar ≥1.16 використовуйте --transformдля застосування трансформації sed regexp до кожного імені файлу (перетворення застосовується на повному шляху в архіві):

tar xf foo.tar --transform 's!^ugly_name\($\|/\)!pretty_name\1!'

Якщо ugly_nameкомпонент верхнього рівня для всіх імен файлів в архіві, вам не потрібно займатись точною відповідністю:

tar xf foo.tar --transform 's/ugly_name/pretty_name/'

Якщо ви не знаєте назви каталогу топлевелю, ви все одно можете скористатися цим методом, хоча ви можете --strip-componentsскоріше віддати перевагу .

tar xf foo.tar --transform 's!^[^/]\+\($\|/\)!pretty_name\1!'

З pax, утилітою архіву POSIX, використовуйте -sопцію, яка бере аргумент заміни sed як аргумент.

pax -rf foo.tar -s '!^ugly_name\($\|/\)!pretty_name\1!'
pax -rf foo.tar -s '/ugly_name/pretty_name/'
pax -rf foo.tar -s '!^[^/]\+\($\|/\)!pretty_name\1!'

9

Використовуй це :

tar -xvf ugly_name.tar
mv ugly_name pretty_name

9
Ви можете скористатись &&оператором списку між цими двома командами, тому друга виконується лише у випадку успіху першої.
манатура

1
Це може мати небажані наслідки, якщо каталог ugly_nameвже існує.
Дрю Дорман

7

Найпростіший спосіб

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1

(1) Це явно не найпростіший спосіб, так як smac89 опублікував відповідь відрізняючи --one-top-level=pretty_nameбез --strip-components 1. (2) І навпаки, прийнята відповідь (розміщена Матом) має функції --strip-components 1без --one-top-level=pretty_name. (3) Чи можете ви пояснити, чому ваша відповідь, поєднуючи ці варіанти, краща за будь-який із старих? Будь ласка, не відповідайте на коментарі; відредагуйте  свою відповідь, щоб зробити її більш зрозумілою та повною.
G-Man

можливо, реальний приклад може допомогти вам уточнити: `wget dev.mysql.com/get/Downloads/MySQL-5.7/… tar xvf mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz --one-top -level = mysql57 --strip-компоненти 1 `
marquicus

Ця відповідь є більш елегантною, ніж відповідь з найбільшою нагодою .
KaiserKatze

@ G-Man --strip-component 1потрібен mkdirабо --strip-components 1методом, або методом, інакше ви просто отримаєте pretty_name/ugly_name/.
davidA

Це справді найпростіший спосіб
smac89

2

Від askUbuntu ця відповідь працювала для мене:

tar zxvf ugly_name.tgz --one-top-level=pretty_name

`- one-top-level [= dir] '

Розповідає tar, щоб створити новий каталог під каталогом вилучення (або той, який перейшов до `-C ') і використовувати його для захисту від tarbombs. За відсутності аргументу dir, ім'я нового каталогу буде дорівнювати базовій назві архіву (ім'я файлу мінус суфікс архіву, якщо його визнано). Будь-які імена учасників, які не починаються з цього імені каталогу (після перетворень з `--transform 'та` --strip-компоненти'), будуть встановлені з ним. Розпізнані суфікси імен файлів - `.tar ', а будь-які суфікси стиснення, розпізнавані див. See -auto-compress .


Оновлення

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


Проблема в тому, що він не перейменовує каталог верхнього рівня, натомість він створює новий рівень, названий pretty_name, з оригінальною каталогом верхнього рівня всередині цього. Наприклад, якщо tar xzf ugly_name.tgzстворили б каталог, який називається ugly_name/, тоді створена команда, яку ви вказали pretty_name/ugly_name/.
davidA

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