Seperti kata Mathias, unzip
tidak memiliki opsi seperti itu, tetapi skrip bash satu-liner dapat melakukan pekerjaan itu.
Masalahnya adalah: pendekatan terbaik tergantung pada tata letak arsip Anda. Sebuah solusi yang mengasumsikan dir level atas tunggal akan gagal total jika konten langsung di root arsip (pikirkan /a/foo
/b/foo
/foo
dan kekacauan pengupasan /a
dan /b
).
Dan kegagalan yang sama terjadi dengan tar --strip-component
. Tidak ada solusi satu ukuran untuk semua.
Jadi, untuk mengupas akar dir, dengan asumsi ada adalah satu (dan hanya satu):
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "${f[@]}"
Pastikan saja file / dirs level kedua tidak memiliki nama yang sama dengan induk level atas (misalnya, /foo/foo
). Tapi /foo/bar/foo
dan /foo/bar/bar
ok. Jika ya, atau Anda hanya ingin aman, Anda bisa menggunakan dir temp untuk ekstraksi:
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" &&
mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"
Jika Anda menggunakan Bash, Anda dapat menguji apakah tingkat atas adalah satu dir atau tidak menggunakan:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "${f[0]}" ]] && echo "Single dir!"
Berbicara tentang Bash, Anda harus menghidupkan dotglob
untuk memasukkan file tersembunyi, dan Anda dapat membungkus semuanya dalam satu fungsi yang berguna:
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"
)
Sekarang masukkan itu ke dalam ~/.bashrc
atau ~/.profile
Anda dan Anda tidak perlu khawatir lagi. Cukup gunakan sebagai:
unzip-strip sourcefile.zip mysubfolder
(pemberitahuan itu akan secara otomatis dibuat mysubfolder
untuk Anda jika tidak ada)