Extractor de archivos comprimidos

Nombre: extract
Autor: Luis Moreno Rodriguez
Lenguaje: Bash
Licencia: GPL
Propósito: Extrae casi cualquier tipo de archivo comprimido
Dependencias: bzip, bzip2, unzip, unrar, arj, unace, uncompress, 7zip

Este script extrae ficheros rar, ISO, ace, zip, bz2, gz, tar, tbz, tgz, 7z, Z, arj y lha. Si el contenido son varios elementos, el archivo se extraerá en una carpeta con el nombre del archivo comprimido y el sufijo "_FILES".

En cualquier caso siempre mostrará donde se descomprime el contenido del fichero. También puede extraer varios archivos a la vez aunque estos estén situados en diferentes directorios. Además soporta paths relativos y absolutos.

extract archivo
#!/bin/bash

# AUTOR: Luis Moreno Rodriguez          2010

function extract () {
    if [ $# = 0 ] || [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
        echo -e "Extract compressed files. If the contents of the file are several elements should be extracted in folder with the name of file and the suffix '_FILES'. Supports relative and absolute paths. Usage '$0 file1 file2...'"
        return
    fi

    for F in $*; do
        if [ ! -f "$F" ]; then echo "$F is not a valid compressed file"
            return
        fi
    done

    for F in $*; do
        local ITEM=`echo ${F##*/}` # the file to extract
        local DIR=`echo ${F%/*}` # the path of the file to extract

        # if de file is not in the actual path
        if [ "$ITEM" != "$DIR" ]; then
            local OLD_PATH=`pwd`
            cd $DIR
        fi

        mkdir ${ITEM}_FILES     #folder where files are extracted
        local ERROR_EXTENSION=0 #FLAG to marks files that not have valid extension
        local RET=0             #the return of the extract command (default 0; no ERROR, OK)

        echo -n "extracting '`pwd`/$ITEM'... "
        case $ITEM in
        *.iso|*.ISO)
           
            local TEMP_DIR=/tmp/deleteme_extract_$$
            mkdir $TEMP_DIR

            if mount -o loop -t iso9660 $ITEM $TEMP_DIR; then
                cp -rf $TEMP_DIR/* ${ITEM}_FILES
                umount $TEMP_DIR
            else
                RET=1
            fi
            rm -rf $TEMP_DIR;;
           
        *)
            cd ${ITEM}_FILES
           
            case $ITEM in
                *.arj|*.ARJ)           arj x -y ../$ITEM &>/dev/null;; # unarj
                *.lha|*.LHA)           lha -x f ../$ITEM &>/dev/null;;
                *.rar|*.RAR)           unrar x -o+ ../$ITEM &>/dev/null;; # rar x
                *.ace|*.ACE)           unace x -o+ ../$ITEM &>/dev/null;;
                *.zip|*.ZIP)           unzip -o ../$ITEM &>/dev/null;;
                *.tar|*.TAR)           tar -xf ../$ITEM &>/dev/null;;
                *.tar.bz2|*.TAR.BZ2)   tar -xjf ../$ITEM &>/dev/null;;
                *.tbz|*.TBZ)           tar -xjf ../$ITEM &>/dev/null;;
                *.tbz2|*.TBZ2)         tar -xjf ../$ITEM &>/dev/null;;
                *.tar.gz|*.TAR.GZ)     tar -xzf ../$ITEM &>/dev/null;;
                *.tgz|*.TGZ)           tar -xzf ../$ITEM &>/dev/null;;
             #   *.bz2|*.BZ2)           bunzip2 -f ../$ITEM &>/dev/null;;  #bunzip2 or bzip2 -d
             #   *.gz|*.GZ)             gunzip -f ../$ITEM &>/dev/null;;
             #   *.Z|*.z)               uncompress -f ../$ITEM &>/dev/null;;
                *.bz2|*.BZ2)           bunzip2 -cf ../$ITEM > ${ITEM%.*};;  #bunzip2 or bzip2 -d
                *.gz|*.GZ)             gunzip -cf ../$ITEM > ${ITEM%.*};;
                *.Z|*.z)               uncompress -cf ../$ITEM > ${ITEM%.*};;
                *.7z|*.7Z)             7z x -y ../$ITEM &>/dev/null;;
                *)   ERROR_EXTENSION=1;;
            esac

            local RET=$?

            case $ITEM in
                *.zip|*.ZIP) if [ $RET -eq 1 ]; then
                                        RET=0
                                        echo -e "WARNING: one or more warning errors were encountered, but processing completed successfully anyway. This includes zipfiles where one or more files was skipped due to unsupported compression method, empty files, or encryption with an unknown password."
                                    fi;;
            esac

            cd ..
        esac

        if [ $RET != 0 ] || [ $ERROR_EXTENSION -eq 1 ]; then
            rm -rf ${ITEM}_FILES     # delete folder

            if [ $ERROR_EXTENSION -eq 1 ]; then
                echo -e "ERROR!\nextract don't know de extension of $ITEM\n"
            else
                echo -e "ERROR!\nThe file $ITEM is not a valid '.${F##*.}' file, or other error ocurred (see below).\n"
            fi
        else
            # looks if the content is one or more files
            if [ `ls ${ITEM}_FILES | wc -w` -eq 1 ]; then
                local EXTRACT_PATH=`pwd`/`ls ${ITEM}_FILES`
                cp -rf ${ITEM}_FILES/* ./
                rm -rf ${ITEM}_FILES
            else
                local EXTRACT_PATH=`pwd`/${ITEM}_FILES
            fi
            echo -e "done!\nall files extracted in $EXTRACT_PATH\n"
        fi
        if [ "$ITEM" != "$DIR" ]; then cd $OLD_PATH; fi
    done

    if [ "$ITEM" != "$DIR" ] && [ ! -f "$EXTRACT_PATH" ] &&  [ $# -eq 1 ]; then
        echo "You want to go to the directory that contains the extracted files?"
        echo -n "[y]es [n]o, default [n]o: "
        read OPTION
        case $OPTION in
        Y|y)    cd $EXTRACT_PATH;;
        esac
    fi
}

extract $*

Nota:

No funciona con archivos comprimidos que tengan espacio es sus nombres.