Wie Mathias sagte, unziphat keine solche Option, aber ein einzeiliges Bash-Skript kann die Arbeit erledigen.
Das Problem ist: Der beste Ansatz hängt von Ihrem Archivlayout ab. Eine Lösung, die ein einzelnes Verzeichnis der obersten Ebene voraussetzt, schlägt fehl, wenn sich der Inhalt direkt im Archivstammverzeichnis befindet (denken Sie über /a/foo /b/foo /foodas Chaos von Stripping /aund /b).
Und das Gleiche passiert mit tar --strip-component. Es gibt keine einheitliche Lösung.
Um das Root-Verzeichnis zu entfernen, vorausgesetzt, es gibt einen (und nur einen):
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "$" Stellen Sie einfach sicher, dass Dateien / Verzeichnisse der zweiten Ebene nicht denselben Namen wie die der obersten Ebene haben (z. B. /foo/foo). Aber /foo/bar/foound /foo/bar/barsind in Ordnung. Wenn dies der Fall ist oder Sie einfach nur sicher sein möchten, können Sie ein temporäres Verzeichnis für die Extraktion verwenden:
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" && mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp" Wenn Sie Bash verwenden, können Sie testen, ob die oberste Ebene ein einzelnes Verzeichnis ist oder nicht verwendet wird:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "$" ]] && echo "Single dir!" Wenn Sie von Bash sprechen, sollten dotglobSie diese Option aktivieren, um versteckte Dateien einzuschließen, und Sie können alles in einer einzigen, praktischen Funktion zusammenfassen:
unzip-strip() ( local zip=$1 local dest=$ local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" && shopt -s dotglob && local f=("$temp"/*) && if (( ${#f[@]} == 1 )) && [[ -d "$" ]] ; then mv "$temp"/*/* "$dest" else mv "$temp"/* "$dest" fi && rmdir "$temp"/* "$temp" ) Jetzt legen Sie das in Ihre ~/.bashrcoder ~/.profileund Sie müssen sich nie wieder darum kümmern. Einfach verwenden als:
unzip-strip sourcefile.zip mysubfolder (Beachten Sie, dass es automatisch mysubfolderfür Sie erstellt wird, wenn es nicht existiert.)