Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions plugins/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ By leveraging these plugins, you can streamline your workflow and tackle coding
| colored-man-pages | Adds a few colors to `man` pages. |
| chezmoi | Dotfile management tool enabling management of user environment configuration. |
| dotnet | This plugin provides completion and useful aliases for .NET Core CLI. |
| extract | This plugin defines a function called `extract` that extracts the archive file you pass it, and it supports a wide variety of archive filetypes. |
| fasd | Utility easing filesystem navigation through shortcuts and abbreviated commands. |
| fzf | A command-line fuzzy finder. |
| gcloud | Command-line tools for interacting with Google Cloud Platform (GCP). |
Expand Down
67 changes: 67 additions & 0 deletions plugins/extract/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# extract plugin

This plugin defines a function called `extract` that extracts the archive file you pass it, and it supports a
wide variety of archive filetypes.

This way you don't have to know what specific command extracts a file, you just do `extract <filename>` and
the function takes care of the rest.

To use it, add `extract` to the plugins array in your zshrc file:

```zsh
plugins=(... extract)
```

## Supported file extensions

| Extension | Description |
| :---------------- | :----------------------------------- |
| `7z` | 7zip file |
| `Z` | Z archive (LZW) |
| `apk` | Android app file |
| `aar` | Android library file |
| `bz2` | Bzip2 file |
| `cab` | Microsoft cabinet archive |
| `cpio` | Cpio archive |
| `deb` | Debian package |
| `ear` | Enterprise Application aRchive |
| `exe` | Windows executable file |
| `gz` | Gzip file |
| `ipa` | iOS app package |
| `ipsw` | iOS firmware file |
| `jar` | Java Archive |
| `lrz` | LRZ archive |
| `lz4` | LZ4 archive |
| `lzma` | LZMA archive |
| `obscpio` | cpio archive used on OBS |
| `rar` | WinRAR archive |
| `rpm` | RPM package |
| `sublime-package` | Sublime Text package |
| `tar` | Tarball |
| `tar.bz2` | Tarball with bzip2 compression |
| `tar.gz` | Tarball with gzip compression |
| `tar.lrz` | Tarball with lrzip compression |
| `tar.lz` | Tarball with lzip compression |
| `tar.lz4` | Tarball with lz4 compression |
| `tar.xz` | Tarball with lzma2 compression |
| `tar.zma` | Tarball with lzma compression |
| `tar.zst` | Tarball with zstd compression |
| `tbz` | Tarball with bzip compression |
| `tbz2` | Tarball with bzip2 compression |
| `tgz` | Tarball with gzip compression |
| `tlz` | Tarball with lzma compression |
| `txz` | Tarball with lzma2 compression |
| `tzst` | Tarball with zstd compression |
| `vsix` | VS Code extension zip file |
| `war` | Web Application archive (Java-based) |
| `whl` | Python wheel file |
| `xpi` | Mozilla XPI module file |
| `xz` | LZMA2 archive |
| `zip` | Zip archive |
| `zlib` | zlib archive |
| `zst` | Zstandard file (zstd) |
| `zpaq` | Zpaq file |

See [list of archive formats](https://en.wikipedia.org/wiki/List_of_archive_formats) for more information
regarding archive formats.

89 changes: 89 additions & 0 deletions plugins/extract/extract.plugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
alias x=extract

extract() {
if [[ $# -eq 0 ]]; then
cat >&2 <<'EOF'
Usage: extract [-option] [file ...]

Options:
-r, --remove Remove archive after unpacking.
EOF
return 1
fi

local remove_archive=1
if [[ "$1" == "-r" || "$1" == "--remove" ]]; then
remove_archive=0
shift
fi

local pwd="$PWD"
while [[ $# -gt 0 ]]; do
if [[ ! -f "$1" ]]; then
echo "extract: '$1' is not a valid file" >&2
shift
continue
fi

local success=0
local file="$1" full_path="$(realpath "$1")"
local extract_dir="${file%.*}"

if [[ "${extract_dir}" =~ ".tar$" ]]; then
extract_dir="${extract_dir%.*}"
fi

if [[ -e "$extract_dir" ]]; then
local rnd="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 5)"
extract_dir="${extract_dir}-${rnd}"
fi

mkdir -p "$extract_dir"
cd "$extract_dir" || return
echo "extract: extracting to $extract_dir" >&2

case "${file,,}" in
*.tar.gz|*.tgz) [[ $(command -v pigz) ]] && tar -I pigz -xvf "$full_path" || tar zxvf "$full_path" ;;
*.tar.bz2|*.tbz|*.tbz2) [[ $(command -v pbzip2) ]] && tar -I pbzip2 -xvf "$full_path" || tar xvjf "$full_path" ;;
*.tar.xz|*.txz) [[ $(command -v pixz) ]] && tar -I pixz -xvf "$full_path" || tar --xz -xvf "$full_path" || xzcat "$full_path" | tar xvf - ;;
*.tar.lzma|*.tlz) tar --lzma -xvf "$full_path" || lzcat "$full_path" | tar xvf - ;;
*.tar.zst|*.tzst) tar --zstd -xvf "$full_path" || zstdcat "$full_path" | tar xvf - ;;
*.tar) tar xvf "$full_path" ;;
*.tar.lz) [[ $(command -v lzip) ]] && tar xvf "$full_path" ;;
*.tar.lz4) lz4 -c -d "$full_path" | tar xvf - ;;
*.tar.lrz) [[ $(command -v lrzuntar) ]] && lrzuntar "$full_path" ;;
*.gz) [[ $(command -v pigz) ]] && pigz -cdk "$full_path" > "${file%.*}" || gunzip -ck "$full_path" > "${file%.*}" ;;
*.bz2) [[ $(command -v pbzip2) ]] && pbzip2 -d "$full_path" || bunzip2 "$full_path" ;;
*.xz) unxz "$full_path" ;;
*.lrz) [[ $(command -v lrunzip) ]] && lrunzip "$full_path" ;;
*.lz4) lz4 -d "$full_path" ;;
*.lzma) unlzma "$full_path" ;;
*.z) uncompress "$full_path" ;;
*.zip) unzip "$full_path" ;;
*.rar) unrar x -ad "$full_path" ;;
*.rpm) rpm2cpio "$full_path" | cpio --quiet -id ;;
*.7z) 7z x "$full_path" ;;
*.deb)
mkdir -p "control" "data"
ar vx "$full_path" > /dev/null
(cd control && extract ../control.tar.*)
(cd data && extract ../data.tar.*)
rm -f *.tar.* debian-binary
;;
*.zst) unzstd --stdout "$full_path" > "${file%.*}" ;;
*.cab|*.exe) cabextract "$full_path" ;;
*.cpio|*.obscpio) cpio -idmvF "$full_path" ;;
*.zpaq) zpaq x "$full_path" ;;
*.zlib) zlib-flate -uncompress < "$full_path" > "${file%.*}" ;;
*)
echo "extract: '$file' cannot be extracted" >&2
success=1 ;;
esac

if [[ $success -eq 0 && $remove_archive -eq 0 ]]; then
rm "$full_path"
fi
shift
cd "$pwd" || return
done
}
Loading