extract.plugin.zsh 2.51 KB
Newer Older
Marc Cornellà's avatar
Marc Cornellà committed
1
alias x=extract
Sorin Ionescu's avatar
Sorin Ionescu committed
2

Marc Cornellà's avatar
Marc Cornellà committed
3
extract() {
4
5
	setopt localoptions noautopushd

Marc Cornellà's avatar
Marc Cornellà committed
6
7
8
	local remove_archive
	local success
	local extract_dir
Sorin Ionescu's avatar
Sorin Ionescu committed
9

Marc Cornellà's avatar
Marc Cornellà committed
10
11
12
	if (( $# == 0 )); then
		cat <<-'EOF' >&2
			Usage: extract [-option] [file ...]
Sorin Ionescu's avatar
Sorin Ionescu committed
13

Marc Cornellà's avatar
Marc Cornellà committed
14
			Options:
15
			    -r, --remove    Remove archive after unpacking.
Marc Cornellà's avatar
Marc Cornellà committed
16
17
		EOF
	fi
Sorin Ionescu's avatar
Sorin Ionescu committed
18

Marc Cornellà's avatar
Marc Cornellà committed
19
20
21
22
23
	remove_archive=1
	if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then
		remove_archive=0
		shift
	fi
Sorin Ionescu's avatar
Sorin Ionescu committed
24

25
	local pwd="$PWD"
Marc Cornellà's avatar
Marc Cornellà committed
26
27
28
29
30
31
	while (( $# > 0 )); do
		if [[ ! -f "$1" ]]; then
			echo "extract: '$1' is not a valid file" >&2
			shift
			continue
		fi
Sorin Ionescu's avatar
Sorin Ionescu committed
32

Marc Cornellà's avatar
Marc Cornellà committed
33
		success=0
34
		extract_dir="${1:t:r}"
35
		local full_path="${1:A}"
36
		case "${1:l}" in
Marc Cornellà's avatar
Marc Cornellà committed
37
38
39
40
41
42
43
44
45
46
			(*.tar.gz|*.tgz) (( $+commands[pigz] )) && { pigz -dc "$1" | tar xv } || tar zxvf "$1" ;;
			(*.tar.bz2|*.tbz|*.tbz2) tar xvjf "$1" ;;
			(*.tar.xz|*.txz)
				tar --xz --help &> /dev/null \
				&& tar --xz -xvf "$1" \
				|| xzcat "$1" | tar xvf - ;;
			(*.tar.zma|*.tlz)
				tar --lzma --help &> /dev/null \
				&& tar --lzma -xvf "$1" \
				|| lzcat "$1" | tar xvf - ;;
47
48
49
50
			(*.tar.zst|*.tzst)
				tar --zstd --help &> /dev/null \
				&& tar --zstd -xvf "$1" \
				|| zstdcat "$1" | tar xvf - ;;
Marc Cornellà's avatar
Marc Cornellà committed
51
			(*.tar) tar xvf "$1" ;;
52
			(*.tar.lz) (( $+commands[lzip] )) && tar xvf "$1" ;;
Aloxaf's avatar
Aloxaf committed
53
			(*.tar.lz4) lz4 -c -d "$1" | tar xvf - ;;
54
			(*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$1" ;;
55
			(*.gz) (( $+commands[pigz] )) && pigz -dk "$1" || gunzip -k "$1" ;;
Marc Cornellà's avatar
Marc Cornellà committed
56
57
			(*.bz2) bunzip2 "$1" ;;
			(*.xz) unxz "$1" ;;
58
			(*.lrz) (( $+commands[lrunzip] )) && lrunzip "$1" ;;
Aloxaf's avatar
Aloxaf committed
59
			(*.lz4) lz4 -d "$1" ;;
Marc Cornellà's avatar
Marc Cornellà committed
60
			(*.lzma) unlzma "$1" ;;
61
			(*.z) uncompress "$1" ;;
62
			(*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl) unzip "$1" -d "$extract_dir" ;;
Marc Cornellà's avatar
Marc Cornellà committed
63
			(*.rar) unrar x -ad "$1" ;;
64
65
66
			(*.rpm)
				command mkdir -p "$extract_dir" && builtin cd -q "$extract_dir" \
				&& rpm2cpio "$full_path" | cpio --quiet -id ;;
Marc Cornellà's avatar
Marc Cornellà committed
67
68
			(*.7z) 7za x "$1" ;;
			(*.deb)
69
70
				command mkdir -p "$extract_dir/control" "$extract_dir/data"
				builtin cd -q "$extract_dir"; ar vx "$full_path" > /dev/null
71
72
				builtin cd -q control; extract ../control.tar.*
				builtin cd -q ../data; extract ../data.tar.*
73
				builtin cd -q ..; command rm *.tar.* debian-binary ;;
74
			(*.zst) unzstd "$1" ;;
75
			(*.cab) cabextract -d "$extract_dir" "$1" ;;
Xeonacid's avatar
Xeonacid committed
76
			(*.cpio) cpio -idmvF "$1" ;;
Marc Cornellà's avatar
Marc Cornellà committed
77
78
79
80
81
			(*)
				echo "extract: '$1' cannot be extracted" >&2
				success=1
			;;
		esac
Sorin Ionescu's avatar
Sorin Ionescu committed
82

83
84
		(( success = success > 0 ? success : $? ))
		(( success == 0 && remove_archive == 0 )) && rm "$full_path"
Marc Cornellà's avatar
Marc Cornellà committed
85
		shift
86
87
88

		# Go back to original working directory in case we ran cd previously
		builtin cd -q "$pwd"
Marc Cornellà's avatar
Marc Cornellà committed
89
	done
Sorin Ionescu's avatar
Sorin Ionescu committed
90
}