Jak wybrać nazwę katalogu podczas rozpakowywania

124

Powiedzmy, że mam nazwany plik ugly_name.tar, który po rozpakowaniu staje się ugly_namekatalogiem. Jakiego polecenia mogę użyć, aby pretty_namezamiast tego powstała nazwa katalogu ?

tshepang
źródło

Odpowiedzi:

171

To powinno działać:

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

-Czmienia określony katalog przed rozpakowaniem (lub spakowaniem). --strip-componentsusuwa określoną liczbę katalogów z nazw plików przechowywanych w archiwum.

Pamiętaj, że tak naprawdę nie jest to przenośne. GNU tar i przynajmniej niektóre tary BSD mają taką --strip-componentsopcję, ale wydaje się, że nie istnieje na innych platformach uniksowych.

Głupi sposób na zrobienie tego działałby jednak prawie wszędzie.

tar xf ugly_name.tar && mv ugly_name pretty_name
Mata
źródło
Myślę, że pozostanę przy głupiej wersji :)
phunehehe
28
@phunehehe: jedną z zalet inteligentnej wersji jest to, że nie musisz z góry wiedzieć, co to jest nieoprawiona nazwa katalogu
tshepang
2
Dodam, że działa to więcej niż „Pretty_name”. W ten sposób możesz także rozpakować do określonego katalogu. Przykład:tar -xvf /tmp/backupfiles.tar -C /var/www/
Generał Redneck
2
Zwykle używam głupiego sposobu i używam symboli wieloznacznych, na wypadek, gdy nie wiem, co to będzie brzydkie imię lub nie chcę go zapisywać. mv ugly-* pretty_name
David Grayson
1
Głupi sposób nie działa, jeśli istnieje już ugly_namekatalog. Nawiasem mówiąc, piękno jest w oku patrzącego.
kmiklas
30

W przypadku GNU tar ≥1,16 użyj, --transformaby zastosować transformację regexp sed do każdej nazwy pliku (transformacja jest stosowana na pełnej ścieżce w archiwum):

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

Jeśli ugly_namejest najwyższym składnikiem wszystkich nazw plików w archiwum, nie musisz zawracać sobie głowy precyzyjnym dopasowaniem:

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

Jeśli nie znasz nazwy katalogu najwyższego poziomu, nadal możesz skorzystać z tej metody, chociaż możesz --strip-componentszamiast tego.

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

Za paxpomocą narzędzia do archiwizacji POSIX użyj -sopcji, która przyjmuje jako argument wyrażenie podobne do 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!'
Gilles
źródło
9

Użyj tego :

tar -xvf ugly_name.tar
mv ugly_name pretty_name
Rupesh Mande
źródło
9
Możesz preferować użycie &&operatora listy między tymi dwoma poleceniami, więc drugie zostanie wykonane tylko wtedy, gdy pierwsze się powiedzie.
manatwork
1
Może to mieć niepożądane konsekwencje, jeśli katalog ugly_namejuż istnieje.
Drew Dormann,
7

Najprostszy sposób

tar xvf dml/ugly_name.tar --one-top-level=pretty_name --strip-components 1
markiz
źródło
(1) To oczywiście nie jest najprostszy sposób, ponieważ smac89 opublikował odpowiedź zawierającą odpowiedź--one-top-level=pretty_name bez --strip-components 1. (2) I odwrotnie, zaakceptowana odpowiedź (opublikowana przez Mat) ma cechy --strip-components 1bez --one-top-level=pretty_name. (3) Czy możesz wyjaśnić, dlaczego Twoja odpowiedź, łącząc te opcje, jest lepsza niż którakolwiek ze starszych? Proszę nie odpowiadać w komentarzach; edytuj  swoją odpowiedź, aby była jaśniejsza i bardziej kompletna.
G-Man,
może prawdziwy przykład może pomóc wyjaśnić: `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-components 1 '
marquicus
Ta odpowiedź jest bardziej elegancka niż ta, która cieszy się największą popularnością .
KaiserKatze
@ G-Man --strip-component 1jest wymagany za pomocą metody mkdirlub --strip-components 1, w przeciwnym razie po prostu otrzymasz pretty_name/ugly_name/.
davidA
To jest rzeczywiście najprostszy sposób
smac89
2

Od askUbuntu ta odpowiedź zadziałała dla mnie:

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

`--one-top-level [= reż]]

Informuje tar, aby utworzył nowy katalog pod katalogiem rozpakowywania (lub ten przekazany do `-C ') i użyje go do ochrony przed tarbombami. W przypadku braku argumentu dir nazwa nowego katalogu będzie równa podstawowej nazwie archiwum (nazwa pliku minus sufiks archiwum, jeśli zostanie rozpoznany). Wszelkie nazwy członków, które nie zaczynają się od tej nazwy katalogu (po przekształceniu z `--transform 'i` --strip-components') będą poprzedzone nią. Rozpoznawane sufiksy nazw plików to „.tar”, a wszelkie sufiksy kompresji rozpoznawane przez See -auto-compress .


Aktualizacja

Jak wskazano w komentarzach , ta metoda nie działa w przypadku poprawnie utworzonych archiwów, jednak jak pokazuje inna odpowiedź , należy dodać, --strip-components 1aby to naprawdę działało. Testowałem z tą nową opcją i działa ona zarówno dla archiwów o nazwie najwyższego poziomu, jak i tych bez.

smac89
źródło
Problem polega na tym, że nie zmienia on nazwy katalogu najwyższego poziomu, zamiast tego tworzy nowy poziom o nazwie pretty_name, w którym znajduje się oryginalny katalog najwyższego poziomu. Np. Jeśli tar xzf ugly_name.tgzutworzy katalog o nazwie ugly_name/, wówczas polecenie, które podałeś, utworzy pretty_name/ugly_name/.
davidA
1
@davidA Dobra uwaga. Zaktualizowałem moją odpowiedź, aby zawierała poprawkę
smac89,