Comme Mathias l'a dit, unzip
cette option n'existe pas, mais un script bash à une ligne peut faire l'affaire.
Le problème est que la meilleure approche dépend de la disposition de vos archives. Une solution supposant un seul répertoire de niveau supérieur échouera misérablement si le contenu se trouve directement dans la racine de l’archive (pensez /a/foo
/b/foo
/foo
au chaos de la suppression /a
et de la suppression /b
).
Et le même échec se produit avec tar --strip-component
. Il n'y a pas de solution unique.
Donc, pour effacer le répertoire racine, en supposant qu’il en existe un (et un seul ):
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"
Assurez-vous simplement que les fichiers / répertoires de deuxième niveau ne portent pas le même nom que le parent de niveau supérieur (par exemple, /foo/foo
). Mais /foo/bar/foo
et /foo/bar/bar
ça va. S'ils le font, ou si vous voulez simplement être en sécurité, vous pouvez utiliser un répertoire temporaire pour l'extraction:
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"
Si vous utilisez Bash, vous pouvez tester si le niveau supérieur est un seul répertoire ou non:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"
En parlant de Bash, vous devez activer dotglob
pour inclure les fichiers cachés, et vous pouvez tout encapsuler dans une seule fonction pratique:
unzip-strip() (
local zip=$1
local dest=${2:-.}
local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
shopt -s dotglob && local f=("$temp"/*) &&
if (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] ; then
mv "$temp"/*/* "$dest"
else
mv "$temp"/* "$dest"
fi && rmdir "$temp"/* "$temp"
)
Maintenant, mettez cela dans votre ~/.bashrc
ou ~/.profile
et vous n'aurez plus jamais à vous en soucier. Utilisez simplement comme:
unzip-strip sourcefile.zip mysubfolder
(notez qu'il sera automatiquement créé mysubfolder
pour vous s'il n'existe pas)