Teerextrakt in Verzeichnis mit gleichem Basisnamen?

18

Ich habe eine Zip-Datei wie myArchive123.tar.gz. Darin befindet sich ein Ordner wiehelloWorld

Wenn ich es extrahiere: tar -xf myArchive123.tar.gzbekomme ich den helloWorldOrdner:

ls 
myArchive123.tar.gz
helloWorld 

Ich möchte, dass die Ausgabe den gleichen Namen wie der Dateiname ohne die Erweiterung .tar.gz hat. Dh:

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

Kann das gemacht werden?

  • Ich weiß nie, was sich im Archiv befindet. Könnte ein Ordner sein, könnte viele Dateien sein.
  • Ich würde gerne ein anderes Tool verwenden, wenn tar das nicht kann.
  • Ich würde ein längeres Formular akzeptieren, das in ein Skript umgewandelt werden kann

EDIT
In der Zwischenzeit habe ich mir ein Skript gehackt, das den Job zu erledigen scheint. (Siehe meine Antwort unten). Wenn es verbessert werden kann, können Sie gerne Kommentare / zusätzliche Antworten posten. Die Hauptsache ist, dass es in einem Einzeiler verpackbar sein sollte, wie:

extract <file>
Leo Ufimtsev
quelle
1
Enthält das Archiv immer genau einen Ordner?
Mark Plotnick
Ich weiß nicht, was zur Extraktionszeit drin ist. Dies sollte auch nicht davon abhängen, was sich im Archiv befindet. Wenn es sich um einen Ordner handelt, extrahieren Sie den Ordner dort. Wenn es sich um eine Datei handelt, extrahieren Sie alle Dateien.
Leo Ufimtsev
In der Zwischenzeit habe ich ein Skript zusammengestellt (siehe unten). Ich kann die Antwort nur in 2 Tagen annehmen.
Leo Ufimtsev
Wird das Archiv jemals mehr als einen Ordner auf der obersten Ebene enthalten?
Mark Plotnick

Antworten:

10

Mit gnu tarkönnten Sie verwenden --xform(oder --transform) zu prepend /prefix/jeden Dateinamen:

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

Anmerkung dort hinführt nicht /in prefix/und die sedExpression Ende mit Ssymbolischen Link - Zielen von Dateinamen Transformationen auszuschließen.
Um es zu testen (Trockenlauf):

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

Um Ihnen den Einstieg zu erleichtern, finden Sie hier ein sehr vereinfachtes Skript, das Sie folgendermaßen aufrufen können extract <file>:

STRIP = $ {1%. *} #Strip letztes Suffix
NAME = $ {STRIP% .tar} #strip .tar- Suffix, falls vorhanden
tar -xf "$ 1" --xform = "s | ^ | $ NAME / | S" #run Befehl
don_crissti
quelle
Dies ist in der Nähe von dem, was ich möchte, mit der Ausnahme, dass ich in der Lage sein möchte, es in etwas zu
packen
Das ist fehlerhaft, es stoppt beim ersten Punkt. Ich habe zB eine Datei wie diese: eclipse-SDK-4.5M6-linux-gtk-x86_64.tar.gz Ich erwarte eine Ausgabe ohne .tar.gz, aber ich bekomme eclipse-sdk-4
Leo Ufimtsev
Im obigen Skript entferne ich die Erweiterung und entferne sie weiter, wenn ich einen 'Teer' finde.
Leo Ufimtsev
Im Allgemeinen mit vielen Arten von Archiven. Ich hatte auf einen schnellen Einzeiler gehofft und dachte, ich vermisse vielleicht eine Argumentationsfahne. Aber es scheint, dass es keine triviale Lösung dafür gibt?
Leo Ufimtsev
Gutes Zeug. Dies funktioniert und ist kürzer als das Skript, das ich geschrieben habe. Nett!
Leo Ufimtsev
7

Nun, Sie könnten es zumindest in ein paar Schritten tun. Wenn du. .. getan hast

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

das würde die Aufgabe erfüllen, obwohl es eine noch kompaktere Antwort geben könnte.

Eric Renouf
quelle
3

Bearbeiten

Die akzeptierte Antwort ist kürzer als die folgende. (Mach dasselbe, aber kürzer ist normalerweise besser).


Ich habe mir schließlich ein Skript für die anstehende Aufgabe gehackt. es funktioniert mit .tar .tar.gz und .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"

Verwendung:

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

Beachten Sie, dass diese Lösung Punkte in einem Dateinamen enthalten kann. ZB Eclipse-4.5M-SDK.tar.gz.

Ich behalte das Drehbuch in meinem Git-Repo. Die neueste Version finden Sie unter: https://github.com/LeoUfimtsev/ldts/blob/master/pathscripts/leo-tar-here

Leo Ufimtsev
quelle
2

Eine weitere mögliche Lösung ist die Verwendung der --transformOption:

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

Mit Ihren Dateien:

tar -xzf myArchive123.tar.gz --transform="s/helloWorld/myArchive123/"
svq
quelle
1
Dies setzt jedoch voraus, dass Sie wissen, was sich im Archiv befindet
Leo Ufimtsev,
zB wie würde ich das in ein einzeiliges Skript umwandeln, ohne zu wissen, was sich im Archiv befindet?
Leo Ufimtsev
Du hast Recht. Es ist nur eine mögliche Lösung, wie ich hier schrieb ...
Svq
Gibt es einen Unterschied zwischen --strip-compoments = 0 myArchive123?
Leo Ufimtsev
1
Und --strip-components=0entfernt einfach den ersten Verzeichnisnamen aus dem Pfad und -Cspeichert mit der Option de-archivierte Dateien in das neue Verzeichnis.
SVQ