function extract if test (count $argv) -lt 1 echo "Usage: extract [output_directory]" return 1 end set output_dir "." set archives $argv # If there's more than one argument, check the last one for a directory if test (count $argv) -gt 1 set maybe_dir $argv[-1] if not test -f $maybe_dir set output_dir $maybe_dir mkdir -p $output_dir set archives $argv[1..-2] end else # If only one argument and it's a file, create directory with same name as archive (without extension) set archive $argv[1] if test -f "$archive" set output_dir (string replace -r '\.(tar\.gz|tgz|tar\.bz2|tbz2|tar\.xz|txz|gz|bz2|xz|zst|zip|7z|rar)$' '' (basename "$archive")) mkdir -p $output_dir end end for archive in $archives if not test -f "$archive" echo "extract: '$archive' is not a valid file" continue end set mime (file --mime-type -b "$archive") switch $mime case 'application/x-tar' tar xvf "$archive" -C "$output_dir" case 'application/gzip' tar xvzf "$archive" -C "$output_dir" ^/dev/null; or gunzip -c "$archive" > "$output_dir/(basename (string replace -r '\.gz$' '' "$archive"))" case 'application/x-bzip2' tar xvjf "$archive" -C "$output_dir" ^/dev/null; or bunzip2 -c "$archive" > "$output_dir/(basename (string replace -r '\.bz2$' '' "$archive"))" case 'application/x-xz' tar xvJf "$archive" -C "$output_dir" ^/dev/null; or unxz -c "$archive" > "$output_dir/(basename (string replace -r '\.xz$' '' "$archive"))" case 'application/zstd' tar --zstd -xvf "$archive" -C "$output_dir" ^/dev/null; or unzstd -c "$archive" > "$output_dir/(basename (string replace -r '\.zst$' '' "$archive"))" case 'application/zip' unzip -j "$archive" -d "$output_dir" case 'application/x-7z-compressed' 7z x "$archive" -o"$output_dir" case 'application/x-rar' 'application/vnd.rar' unrar x -o+ "$archive" "$output_dir" case '*' echo "extract: unknown file type for '$archive' ($mime)" continue end end end