wypakować tar do katalogu o tej samej nazwie bazowej?

18

Mam spakowany plik jak myArchive123.tar.gz. Wewnątrz zawiera folder podobny dohelloWorld

Jeśli go rozpakuję: tar -xf myArchive123.tar.gzotrzymam helloWorldfolder:

ls 
myArchive123.tar.gz
helloWorld 

Chciałbym, aby wyjście miało taką samą nazwę jak nazwa pliku minus rozszerzenie .tar.gz. To znaczy:

tar <magic paramaters> myArchive123.tar.gz 
ls 
 myArchive123.tar.gz
 myArchive123
cd myArchive123
ls 
  helloWorld

Czy można to zrobić?

  • Nigdy nie wiem, co jest w archiwum. Może to być folder, może być wiele plików.
  • Byłbym w porządku, używając innego narzędzia, jeśli tar nie może tego zrobić.
  • Byłbym w porządku z dłuższą formą, którą można przekształcić w skrypt

EDYCJA
W międzyczasie zhakowałem sobie skrypt, który wydaje się, że wykonałem zadanie. (patrz moja opublikowana odpowiedź poniżej). Jeśli można to poprawić, prosimy dodawać komentarze / dodatkowe odpowiedzi. Najważniejsze jest to, że powinien on być pakowany w jedno-liniowy materiał, taki jak:

extract <file>
Lew Ufimcew
źródło
1
Czy archiwum zawsze zawiera dokładnie jeden folder?
Mark Plotnick
Nie wiem, co jest w środku w czasie ekstrakcji. Nie powinno to również zależeć od tego, co znajduje się w archiwum. Jeśli jest to folder, rozpakuj tam folder. jeśli jest to plik, wypakuj wszystkie pliki.
Lew Ufimcew
W międzyczasie poskładałem skrypt (patrz poniżej). Mogę zaakceptować odpowiedź tylko za 2 dni.
Lew Ufimcew
Czy archiwum kiedykolwiek będzie zawierało więcej niż jeden folder na najwyższym poziomie?
Mark Plotnick,

Odpowiedzi:

10

Za gnu tarpomocą --xform(lub --transform) możesz dodać /prefix/do nazwy każdego pliku:

tar -xf myArchive.tar.gz --xform='s|^|myArchive/|S'

uwaga nie ma wiodących /w prefix/a sedkońce wyrażenia z Swykluczyć symboliczne cele link z przekształceń nazw plików.
Aby to przetestować (na sucho):

tar -tf myArchive.tar.gz --xform='s|^|myArchive/|S' --verbose --show-transformed-names

Na początek znajdziesz bardzo uproszczony skrypt, który możesz wywołać jako extract <file>:

PASEK = $ {1%. *} #Strip ostatni przyrostek
NAME = $ {STRIP% .tar} #strip .tar sufiks, jeśli jest obecny
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" # run
don_crissti
źródło
Jest to bliskie temu, czego chcę, z wyjątkiem tego, że chciałbym móc spakować go w coś takiego: wyodrębnij <plik>
Leo Ufimcew
To jest błędne, zatrzymuje się przy pierwszej kropce. Np. Mam taki plik: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Oczekuję wyjścia bez pliku .tar.gz, ale dostaję eclipse-sdk-4
Leo Ufimtsev
W powyższym skrypcie usuwam rozszerzenie i usuwam je dalej, jeśli znajdę „tar”.
Leo Ufimcew
Ogólnie rzecz biorąc, z wieloma rodzajami archiwów. Miałem nadzieję na szybki jednoliniowy, pomyślałem, że może brakuje mi flagi argumentu. Ale wydaje się, że nie ma na to trywialnego rozwiązania?
Leo Ufimcew
Dobry towar. To działa i jest krótsze niż skrypt, który napisałem. Ładny!
Leo Ufimcew
7

Cóż, możesz to zrobić przynajmniej w kilku krokach. Jeśli tak

mkdir <archive name>
tar -xf <archive name>.tar.gz --strip-components=1 -C <archive name>

spełniłoby to zadanie, choć może być jeszcze bardziej zwięzła odpowiedź.

Eric Renouf
źródło
3

Edytować

Akceptowana odpowiedź jest krótsza niż poniżej. (zrób to samo, ale zwykle krótszy jest zwykle lepszy).


W końcu zhakowałem sobie skrypt dla tego zadania. współpracuje z .tar .tar.gz i .gz

#!/bin/sh
#usage:
# nameOfScript myArchive.tar.gz
# nameOfScript myArchive.gz
# nameOfScript myArchive.tar
#
# Result:
# myArchive   //folder
fileName="${1%.*}" #extracted filename

#handle the case of archive.tar.gz
trailingExtension="${fileName##*.}"
if [ "$trailingExtension" == "tar" ]  
then
    fileName="${fileName%.*}"  #remove trailing  tar.
fi

mkdir "$fileName"
tar -xf "$1" --strip-components=0 -C "$fileName"

Stosowanie:

   nameOfScript archive.tar.gz 
   ls 
    archive
   cd archive 
   ls 
    <archive content>

Uwaga: to rozwiązanie może zawierać kropki w nazwie pliku. Np. Eclipse-4.5M-SDK.tar.gz.

Trzymam skrypt w moim repozytorium git. Aby uzyskać najnowszą wersję, zobacz: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here

Lew Ufimcew
źródło
2

Jeszcze jednym możliwym rozwiązaniem jest użycie --transformopcji:

tar -xzf ARCHIVE_NAME.tgz --transform="s/OLD_DIR_NAME/ARCHIVE_NAME/"

Z twoimi plikami:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
svq
źródło
1
ale to zakłada, że ​​wiesz, co jest w archiwum
Lew Ufimcew
np. jak zamienić to w skrypt jednowierszowy, nie wiedząc, co jest w archiwum?
Lew Ufimcew
Masz rację. To tylko jedno możliwe rozwiązanie, jak tu napisałem ...
svq
czy jest jakaś różnica między tym a --strip-compoments = 0 myArchive123?
Leo Ufimcew
1
I --strip-components=0po prostu usuwa nazwę pierwszego katalogu ze ścieżki, a przy -Copcji zapisuje pliki zarchiwizowane w nowym katalogu.
svq