Last active
March 4, 2026 14:20
-
-
Save Menchen/11600e8e5fb4eb37464bffe5ea8d4f57 to your computer and use it in GitHub Desktop.
Smarter modern extract zsh function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| extract() { | |
| local remove_archive=0 | |
| local list_only=0 | |
| local custom_dest="" | |
| local files=() | |
| # 1. Advanced Argument Parsing | |
| while (( $# > 0 )); do | |
| case "$1" in | |
| -r|--remove) remove_archive=1; shift ;; | |
| -l|--list) list_only=1; shift ;; | |
| -d|--dest) | |
| if [[ -z "$2" ]]; then echo "Error: -d requires a directory path."; return 1; fi | |
| custom_dest="${2:A}" # Convert to absolute path immediately | |
| shift 2 | |
| ;; | |
| -*) echo "extract: Unknown option: $1"; return 1 ;; | |
| *) files+=("$1"); shift ;; | |
| esac | |
| done | |
| if (( ${#files[@]} == 0 )); then | |
| echo "Usage: extract [-r] [-l] [-d <path>] <archive1> ..." | |
| return 1 | |
| fi | |
| # 2. Process each file | |
| for file in "${files[@]}"; do | |
| if [[ ! -f "$file" ]]; then | |
| echo "extract: '$file' is not a valid file" | |
| continue | |
| fi | |
| local success=0 | |
| local abs_file="${file:A}" | |
| # --------------------------------------------------------- | |
| # FEATURE: Clean List with Human-Readable Sizes (-l) | |
| # --------------------------------------------------------- | |
| if (( list_only == 1 )); then | |
| echo "🔍 Contents of: ${file:t}" | |
| echo " ├───────────┼──────────────────────────────────────" | |
| local list_output="" | |
| # Master Formatter: Converts bytes to Human Readable and prints the table row | |
| local fmt_awk=' | |
| BEGIN { | |
| FS="\t" | |
| split("B KB MB GB TB PB EB ZB YB", unit, " ") | |
| } | |
| { | |
| bytes=$1; path=$2 | |
| if (path == "") next | |
| if (bytes !~ /^[0-9]+$/) { | |
| printf " │ %-9s │ %s\n", "-", path | |
| next | |
| } | |
| size=bytes | |
| u=1 | |
| while (size>=1024 && u<5) { size/=1024; u++ } | |
| if (u==1) size_str=sprintf("%d %s", size, unit[u]) | |
| else size_str=sprintf("%.1f %s", size, unit[u]) | |
| printf " │ %-9s │ %s\n", size_str, path | |
| }' | |
| # Parser for both BSD and GNU tar outputs (dynamically finds the size column) | |
| local tar_awk='{ | |
| for(i=3; i<=NF; i++) { | |
| # Looks for the date column to find the size right before it | |
| if ($i ~ /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/ || $i ~ /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)$/) { | |
| size=$(i-1); p_start=i+2; if ($i ~ /^[a-zA-Z]+$/) p_start=i+3 | |
| path=$(p_start); for(j=p_start+1; j<=NF; j++) path=path " " $j | |
| print size "\t" path | |
| break | |
| } | |
| } | |
| }' | |
| # Parser for 7-Zip machine-readable output | |
| local p7z_awk=' | |
| /^Path = / { p=substr($0, 8) } | |
| /^Size = / { s=substr($0, 8); if (p != "" && p != arch) { print s "\t" p }; p=""; s="" }' | |
| # Parser for Unzip quiet-list output | |
| local unzip_awk='{ size=$1; match($0, /[0-9]{2}:[0-9]{2} +/); if(RSTART){ path=substr($0, RSTART+RLENGTH); print size "\t" path } }' | |
| case "${file:l}" in | |
| *.tar|*.tar.*|*.tgz|*.tbz|*.txz|*.tlz|*.tzst) | |
| list_output=$(tar tvf "$abs_file" 2>/dev/null | awk "$tar_awk" | awk "$fmt_awk") ;; | |
| *.zip|*.apk|*.jar|*.war|*.ear|*.cbz) | |
| if (( $+commands[unzip] )); then list_output=$(unzip -qql "$abs_file" 2>/dev/null | awk "$unzip_awk" | awk "$fmt_awk") | |
| elif (( $+commands[7z] )); then list_output=$(7z l -slt "$abs_file" 2>/dev/null | awk -v arch="${file:t}" "$p7z_awk" | awk "$fmt_awk") | |
| elif (( $+commands[bsdtar] )); then list_output=$(bsdtar -tvf "$abs_file" 2>/dev/null | awk "$tar_awk" | awk "$fmt_awk"); fi ;; | |
| *.rar|*.cbr) | |
| if (( $+commands[7z] )); then list_output=$(7z l -slt "$abs_file" 2>/dev/null | awk -v arch="${file:t}" "$p7z_awk" | awk "$fmt_awk") | |
| # unrar vb lacks sizes, so we pass "-" to bypass the size calculator | |
| elif (( $+commands[unrar] )); then list_output=$(unrar vb "$abs_file" 2>/dev/null | awk '{ print "-\t" $0 }' | awk "$fmt_awk"); fi ;; | |
| *.7z|*.cb7|*.iso|*.img|*.dmg|*.cab|*.wim) | |
| if (( $+commands[7z] )); then list_output=$(7z l -slt "$abs_file" 2>/dev/null | awk -v arch="${file:t}" "$p7z_awk" | awk "$fmt_awk") | |
| elif (( $+commands[bsdtar] )); then list_output=$(bsdtar -tvf "$abs_file" 2>/dev/null | awk "$tar_awk" | awk "$fmt_awk"); fi ;; | |
| *.deb) | |
| if (( $+commands[dpkg-deb] )); then list_output=$(dpkg-deb --fsys-tarfile "$abs_file" 2>/dev/null | tar tvf - | awk "$tar_awk" | awk "$fmt_awk") | |
| elif (( $+commands[ar] )); then list_output=$(ar t "$abs_file" 2>/dev/null | awk '{ print "-\t" $0 }' | awk "$fmt_awk"); fi ;; | |
| *.rpm) | |
| if (( $+commands[rpm2cpio] )) && (( $+commands[cpio] )); then | |
| list_output=$(rpm2cpio "$abs_file" 2>/dev/null | cpio -tv --quiet 2>/dev/null | awk "$tar_awk" | awk "$fmt_awk") | |
| fi ;; | |
| *.gz|*.bz2|*.xz|*.zst|*.lzma|*.lz4|*.br|*.lz|*.z) | |
| local s="-" | |
| # Specifically try to peek at uncompressed size for gz | |
| if (( $+commands[gzip] )) && [[ "${file:l}" == *.gz ]]; then s=$(gzip -l "$abs_file" 2>/dev/null | awk 'NR==2 {print $2}'); fi | |
| list_output=$(echo "$s\t${file:t:r}" | awk "$fmt_awk") ;; | |
| *) echo " │ ❌ Listing not supported for this format." ;; | |
| esac | |
| if [[ -n "$list_output" ]]; then | |
| echo "$list_output" | |
| else | |
| echo " │ ❌ Could not read archive contents." | |
| fi | |
| echo " ╰───────────┴──────────────────────────────────────" | |
| echo "" # Blank line for spacing between multiple files | |
| continue # Skip extraction and move to the next file | |
| fi | |
| # --------------------------------------------------------- | |
| # Path & Directory Generation | |
| # --------------------------------------------------------- | |
| local base_name="${file:t:r}" | |
| base_name="${base_name%.tar}" | |
| if [[ -z "$base_name" || "$base_name" == "${file:t}" ]]; then | |
| base_name="${file:t}_extracted" | |
| fi | |
| # Apply custom destination if provided | |
| local dest_dir="" | |
| if [[ -n "$custom_dest" ]]; then | |
| dest_dir="${custom_dest}/${base_name}" | |
| else | |
| dest_dir="${base_name}" | |
| fi | |
| local needs_dir=1 | |
| local final_output_path="" | |
| case "${file:l}" in | |
| *.gz|*.bz2|*.xz|*.zst|*.zstd|*.lzma|*.lz|*.z|*.lz4|*.br) | |
| needs_dir=0 | |
| # If custom dest is set, put the single file there | |
| if [[ -n "$custom_dest" ]]; then | |
| mkdir -p "$custom_dest" | |
| final_output_path="${custom_dest}/${file:t:r}" | |
| else | |
| final_output_path="${file:r}" | |
| fi | |
| ;; | |
| esac | |
| # Create destination directory with Base36 random suffix | |
| if (( needs_dir )); then | |
| if [[ -d "$dest_dir" ]]; then | |
| local base_dest="$dest_dir" | |
| while [[ -d "$dest_dir" ]]; do | |
| local rand_math=$(( [##36] RANDOM * RANDOM )) | |
| local rnd="${(L)rand_math:1:5}" | |
| dest_dir="${base_dest}-${rnd}" | |
| done | |
| fi | |
| mkdir -p "$dest_dir" | |
| echo "📂 Extracting to: $dest_dir/" | |
| final_output_path="$dest_dir" | |
| fi | |
| # 3. Intelligent Extraction Logic (with Execution Fall-Through) | |
| case "${file:l}" in | |
| *.zip|*.apk|*.jar|*.war|*.ear|*.cbz) | |
| if (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[7za] )) && 7za x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[unzip] )) && unzip -q "$abs_file" -d "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[bsdtar] )) && bsdtar -xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar.lzma|*.tlz) | |
| tar xf "$abs_file" -C "$dest_dir" 2>/dev/null && success=1 | |
| if (( success == 0 )); then | |
| if (( $+commands[lzcat] )) && lzcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[xzcat] )) && xzcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi | |
| fi ;; | |
| *.tar.zst|*.tzst) | |
| if tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[zstdcat] )) && zstdcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar.lz) | |
| if tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[lzip] )) && lzip -cd "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar.gz|*.tgz) | |
| if tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[pigz] )) && pigz -dc "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[zcat] )) && zcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar.bz2|*.tbz|*.tbz2) | |
| if tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[pbzip2] )) && pbzip2 -dc "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[bzcat] )) && bzcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar.xz|*.txz) | |
| if tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[xzcat] )) && xzcat "$abs_file" | tar xf - -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.tar) | |
| if (( $+commands[tar] )) && tar xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[bsdtar] )) && bsdtar -xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.7z|*.cb7) | |
| if (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[7za] )) && 7za x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[7zr] )) && 7zr x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[bsdtar] )) && bsdtar -xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.rar|*.cbr) | |
| if (( $+commands[unrar] )) && unrar x "$abs_file" "$dest_dir/" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[bsdtar] )) && bsdtar -xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.deb) | |
| if (( $+commands[dpkg-deb] )) && dpkg-deb -x "$abs_file" "$dest_dir" 2>/dev/null; then success=1 | |
| elif (( $+commands[ar] )) && (cd "$dest_dir" && ar x "$abs_file" 2>/dev/null); then success=1 | |
| elif (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1; fi ;; | |
| *.rpm) | |
| if (( $+commands[rpm2cpio] )) && (( $+commands[cpio] )) && (cd "$dest_dir" && rpm2cpio "$abs_file" 2>/dev/null | cpio -idmv -W none 2>/dev/null); then success=1 | |
| elif (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1; fi ;; | |
| *.dmg) | |
| if (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[hdiutil] )) && hdiutil attach "$abs_file" -mountpoint "$dest_dir" >/dev/null 2>&1; then success=1; fi ;; | |
| *.iso|*.img|*.cab|*.wim|*.swm|*.esd) | |
| if (( $+commands[7z] )) && 7z x "$abs_file" -o"$dest_dir" >/dev/null 2>&1; then success=1 | |
| elif (( $+commands[bsdtar] )) && bsdtar -xf "$abs_file" -C "$dest_dir" 2>/dev/null; then success=1; fi ;; | |
| *.gz) | |
| if (( $+commands[pigz] )) && pigz -dc "$abs_file" > "$final_output_path" 2>/dev/null; then success=1 | |
| elif (( $+commands[gunzip] )) && gunzip -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.bz2) | |
| if (( $+commands[pbzip2] )) && pbzip2 -dc "$abs_file" > "$final_output_path" 2>/dev/null; then success=1 | |
| elif (( $+commands[bunzip2] )) && bunzip2 -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.xz) | |
| if (( $+commands[unxz] )) && unxz -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.zst|*.zstd) | |
| if (( $+commands[unzstd] )) && unzstd -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.lzma) | |
| if (( $+commands[unlzma] )) && unlzma -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1 | |
| elif (( $+commands[lzcat] )) && lzcat "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.lz4) | |
| if (( $+commands[lz4] )) && lz4 -d "$abs_file" "$final_output_path" >/dev/null 2>&1; then success=1; fi ;; | |
| *.br) | |
| if (( $+commands[brotli] )) && brotli -c -d "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.lz) | |
| if (( $+commands[lzip] )) && lzip -dc "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *.z) | |
| if (( $+commands[uncompress] )) && uncompress -c "$abs_file" > "$final_output_path" 2>/dev/null; then success=1; fi ;; | |
| *) | |
| echo "extract: '$file' cannot be extracted by this function" | |
| if (( needs_dir )); then rmdir "$dest_dir" 2>/dev/null; fi | |
| continue | |
| ;; | |
| esac | |
| # 4. Clean up or Report Success | |
| if (( success == 0 )); then | |
| if (( needs_dir )); then rmdir "$dest_dir" 2>/dev/null; fi | |
| # Also clean up empty single file attempts | |
| if (( needs_dir == 0 )) && [[ -f "$final_output_path" ]]; then rm -f "$final_output_path"; fi | |
| echo "❌ Extraction failed for '$file'." | |
| else | |
| # If final_output_path is absolute, don't prepend pwd | |
| if [[ "$final_output_path" = /* ]]; then | |
| echo "✨ Successfully extracted to: $final_output_path" | |
| else | |
| echo "✨ Successfully extracted to: $(pwd)/$final_output_path" | |
| fi | |
| if (( remove_archive == 1 )); then | |
| echo "🗑️ Removed original archive: '$file'" | |
| rm -f "$file" | |
| fi | |
| fi | |
| echo "----------------------------------------" | |
| done | |
| } | |
| _extract() { | |
| local -a supported_exts=( | |
| "*.zip" "*.apk" "*.jar" "*.war" "*.ear" "*.cbz" | |
| "*.tar" "*.tar.gz" "*.tgz" "*.tar.bz2" "*.tbz" "*.tbz2" "*.tar.xz" "*.txz" | |
| "*.tar.lzma" "*.tlz" "*.tar.zst" "*.tzst" "*.tar.lz" | |
| "*.7z" "*.cb7" "*.rar" "*.cbr" | |
| "*.deb" "*.rpm" "*.dmg" "*.iso" "*.img" "*.cab" "*.wim" "*.swm" "*.esd" | |
| "*.gz" "*.bz2" "*.xz" "*.zst" "*.zstd" "*.lzma" "*.lz4" "*.br" "*.lz" "*.z" | |
| ) | |
| local glob_str="${(j: :)supported_exts}" | |
| _arguments -s \ | |
| '(-r --remove)'{-r,--remove}'[Remove original archive after successful extraction]' \ | |
| '(-l --list)'{-l,--list}'[List archive contents without extracting]' \ | |
| '(-d --dest)'{-d,--dest}'[Extract to a specific destination directory]:directory:_directories' \ | |
| "*:archive file:_files -g '$glob_str'" | |
| } | |
| alias x=extract | |
| compdef _extract extract x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment