Wie kann ich unzip / zip zwingen, beim Extrahieren kein Unterverzeichnis zu erstellen?


19

Abhängig davon, wie eine Zip-Datei erstellt wird, werden manchmal alle Dateien direkt extrahiert, und manchmal werden die Dateien in ein Unterverzeichnis extrahiert.

Wenn letzteres zutrifft, wie kann ich den unzipBefehl erzwingen , dieses Verzeichnis der ersten Ebene zu "ignorieren"?

Beispiel:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
mkdir omeka
unzip omeka-1.5.1.zip -d omeka/
cd omeka/
ll

Was ich bekomme ist /tmp/omeka/omeka-1.5.1/:

total 12
drwxr-xr-x 3 root root 4096 2012-05-08 18:44 ./
drwxrwxrwt 6 root root 4096 2012-05-08 18:44 ../
drwxr-xr-x 5 root root 4096 2012-04-20 14:54 omeka-1.5.1/

Was ich will, ist von den Dateien extrahiert /tmp/omeka/, (eine Ebene höher und keine Versionsnummer in der Verzeichnisstruktur enthalten)

/tmp/omeka/(files)

Ich weiß, dass ich die -jOption "Junk-Pfade" verwenden kann, aber ich möchte die Unterverzeichnisstruktur beibehalten, nur nicht die Verzeichnisstruktur der obersten Ebene. Wie kann ich das machen?


ps: Mir ist bewusst, dass ich mvdie Dateien extrahieren und dann , aber ich wollte sehen, ob es eine Möglichkeit gibt, dies direkt mit dem Befehl
unzip

Mir ist keiner bekannt. Wenn der Dateiname (abgesehen von der Erweiterung) immer mit dem Verzeichnisnamen übereinstimmt, ist es ziemlich einfach, die Umbenennung des extrahierten Verzeichnisses per Skript durchzuführen.
Mat

3
Ich verstehe, was Sie versuchen, aber ich würde es nicht empfehlen. Das Entfernen der Versionsnummer aus Ihren Projektquellen ist eine schlechte Idee. Sie sollten einfach normal extrahieren und ein ln -s verwenden, wenn Sie einen kürzeren Namen ohne Versionsinformationen wünschen. Auf diese Weise wissen Sie immer, welche Version Sie ausführen, und können durch Wechseln des Links problemlos auf eine neue Version aktualisieren.
Burton Samograd

@BurtonSamograd - das wäre ideal, aber ich bin immer noch gespannt, ob es einen effektiven Weg gibt, weil einige Software, am Beispiel von Wordpress, jede Version in ein /wordpress/Verzeichnis (keine Versionsnummer) in der Zip-Datei legt . Es ist in der Tat in Ordnung unzipund dann, mvaber keine Kontrolle darüber zu haben und es in zwei Schritten tun zu müssen, hat mich immer ein wenig auf die Nerven gebracht. Zum Glück kommt Wordpress auch in einer .tar.gzGeschmacksrichtung :)
CWD

Versuchen Siecd /tmp/omeka && ln -s -T . omeka-1.5.1
James Youngman

Antworten:


4

Verwenden Sie ein FUSE- Dateisystem, mit dem Sie Archive wie Verzeichnisse wie AVFS durchsuchen können . Verwenden Sie cpdiese Option, um die Dateien in ein Verzeichnis Ihrer Wahl zu extrahieren.

mountavfs
cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/omeka-1.5.1 omeka

Da wir davon ausgehen, dass sich im Archiv ein einzelnes Verzeichnis auf oberster Ebene befindet, können Sie dieses auf kürzen

cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/* omeka

@ Giles, du bist der Experte, der kommt und alle Fragen beantwortet, die niemand sonst beantworten kann. Ich denke, das ist wirklich der einzige Weg, dies zu tun. Ich hatte gehofft, unzipetwas Magie zu haben, um dies zu tun, wie zum Beispiel die Angabe der zu extrahierenden Dateien */*, die ich verwenden könnte, ohne ein anderes Dienstprogramm zu installieren, aber ich denke nicht. Vielen Dank. +1
KWD

6

Wenn Ihre Zip-Datei keine Verzeichnisstruktur enthält oder Sie sie nicht beibehalten müssen, können Sie dies verwenden:

cd /tmp
wget http://omeka.org/files/omeka-1.5.1.zip
unzip -j omeka-1.5.1.zip -d omeka
cd omeka
ll

3

Dieses Skript ist nicht robust, funktioniert aber in einfachen Fällen:

...
dest=omeka
unzip omeka-1.5.1.zip -d $dest/

if [ `ls $dest | wc -l` == 1 ]; then
  subdir=`ls $dest`
  mv $dest/$subdir/* $dest/
  rmdir $dest/$subdir
fi

Es wird nur geprüft, ob es genau ein Unterverzeichnis gibt. Wenn dies der Fall ist, wird alles nach oben verschoben und dann gelöscht.


2

Ich habe mich gerade registriert, kann also die Antwort von @SteveBennet nicht positiv bewerten und dort keinen Kommentar hinzufügen.

Basierend auf seiner Antwort habe ich eine rekursive Funktion wie diese erstellt:

...

shopt -s dotglob # To include hidden files in the move command

function moveSub {
  local dest=$1
  if [ `ls $dest | wc -l` == 1 ]; then
    local subdir=`ls $dest`
    moveSub "$dest/$subdir"
    mv $dest/$subdir/* $dest/
    rmdir $dest/$subdir
  fi
}

moveSub "$dest"

Genau wie @SteveBennet sagte: Dieses Skript ist nicht robust, funktioniert aber in den einfachen Fällen.

Hoffe es ist nützlich.


1

Notwendigkeit sieht nach patch --strip=nOption aus

Es wäre wünschenswert, eine Option wie patch --strip=number(oder -pnumber) zu haben, die numberPfadkomponenten am Anfang zerlegt (siehe Vergleichen und Zusammenführen von Dateien: Patch-Verzeichnisse ).

Andere Lösung, Anwendbarkeit

Gelingt dies nicht, gibt es eine andere Lösung, die irgendwie hackisch ist, aber funktioniert. In meinem Fall wollte ich ein Verzeichnis mit vorhandenen Dateien mit dem Inhalt einer Zip-Datei überschreiben, ohne zuerst die vollständige Zip-Datei zu extrahieren.

Wenn diese Lösung funktioniert und die Lösung von @ Gilles verfügbar ist, funktioniert auch diese. Für diese Lösung ist jedoch kein FUSE-Dateisystem erforderlich.

Wie es geht

Vorausgesetzt, Sie kennen das zusätzliche Verzeichnis. In diesem Fall omeka-1.5.1können Sie dies tun:

mkdir omeka
ln -s . omeka/omeka-1.5.1 # create a symlink that redirects output
unzip omeka-1.5.1.zip -d omeka/
rm omeka/omeka-1.5.1 # remote symlink

unzipversuche zu entpacken zu omeka-1.5.1dem eigentlich ein symlink zu dir gehört. Infolgedessen landen Dateien omekadirekt in.

Mögliche Varianten

Sie können sich Varianten vorstellen, um einen oder mehrere Teile einer Depeer-Hierarchie umzuleiten.

ln -s ../myfoo omeka/omeka-1.5.1/foo
ln -s ../../mybarxyzzy omeka/omeka-1.5.1/subdir/bar

Fazit

Diese Lösung ist etwas spezifisch, hat aber ihre Anwendungsfälle und ich habe sie gerade benutzt.


Gute Lösung, wenn Sie den Weg kennen!
Grepsedawk

Der Pfad kann abgefragt werden, indem zuerst der Zip-Inhalt aufgelistet wird, z unzip -l. B. mit . Dies könnte sogar mithilfe eines Skripts automatisiert werden, das einen Teil des üblichen Pfads ermittelt.
Stéphane Gourichon

Oh, total, es ist nur eine Tonne einfacher, wenn du den Weg kennst. Ich habe ein bisschen mit unzip -l gespielt, aber es war ein bisschen mehr grep / sed / awk, als ich beabsichtigt hatte, also bin ich zurückgetreten.
Grepsedawk

zipinfo -1könnte ein guter Anfang sein. Was ist Ihr Anwendungsfall?
Stéphane Gourichon

github.com/grepsedawk/wow-config/blob/… in diesem Fall kenne ich das Verzeichnis :)
grepsedawk

1

Höchstwahrscheinlich möchten Sie unzipmit der -jOption ausgeführt werden, wie in:

unzip -j files.zip -d ./output/

Aber Sie könnten von seinem Verhalten überrascht sein:

-j Junk-Pfade. Die Verzeichnisstruktur des Archivs wird nicht neu erstellt. Alle Dateien werden im Extraktionsverzeichnis abgelegt (standardmäßig das aktuelle).

Wenn Sie files.zipim Ausgabeverzeichnis extrahieren ./outputund dies als Ergebnis erhalten:

./output/files/subfolder1/f1
./output/files/subfolder1/f2

dann gibt die -jOption Folgendes aus (alle Pfade gestreift):

./output/f1
./output/f2
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.