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>

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

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ź.


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


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/"

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.