Como dijo Mathias, unzip
no tiene esa opción, pero un script bash de una sola línea puede hacer el trabajo.
El problema es: el mejor enfoque depende de su diseño de archivo. Una solución que asume que un único directorio de nivel superior fallará miserablemente si el contenido está directamente en la raíz del archivo (piense /a/foo
/b/foo
/foo
y el caos de la eliminación /a
y /b
).
Y ocurre el mismo error con tar --strip-component
. No existe una solución única para todos.
Por lo tanto, para quitar el directorio raíz, suponiendo que no es uno (y solamente uno):
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"
Solo asegúrese de que los archivos / directorios de segundo nivel no tengan el mismo nombre del padre de nivel superior (por ejemplo /foo/foo
). Pero /foo/bar/foo
ya /foo/bar/bar
están bien. Si lo hacen, o si solo quieres estar seguro, puedes usar un directorio temporal para la extracción:
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"
Si está utilizando Bash, puede probar si el nivel superior es un directorio único o no:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"
Hablando de Bash, debe activar dotglob
para incluir archivos ocultos, y puede envolver todo en una sola función práctica:
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"
)
Ahora pon eso en tu ~/.bashrc
o ~/.profile
y nunca más tendrás que preocuparte por eso. Simplemente use como:
unzip-strip sourcefile.zip mysubfolder
(observe que se creará automáticamente mysubfolder
para usted si no existe)