2

I want to extract a tar.bz2 file to specific folder. Problem is that tar xjf will extract the content without extracting to a folder. Assume I have 1.tar.bz2. I want to have a result like this

1/a.txt
1/b.txt
...

However right now, I see only

a.txt
b.txt
....

What should I do? I am looking for an automated solution. In windows, winrar has option "extract to" a folder which has the name as the rar file

2

2 Answers 2

2
mkdir 1 
tar xf archive.tar -C 1

function untar2folder {
    local folder=`echo "$1" |
    sed -E 's/(\.)?(tar|t)?(\.)?(gz|z|bz2|bz|lz|lzma|xz)$//'`
    mkdir "$folder"
    tar xf "$1" -C "$folder";
}

references
Gentoo /usr/bin/lesspipe.sh

#!/bin/bash
#
# Preprocessor for 'less'. Used when this environment variable is set:
# LESSOPEN="|lesspipe %s"

# TODO: handle compressed files better

[[ -n ${LESSDEBUG} ]] && set -x

trap 'exit 0' PIPE

guesscompress() {
    case "$1" in
        *.gz|*.z)   echo "gunzip -c" ;;
        *.bz2|*.bz) echo "bunzip2 -c" ;;
        *.lz)       echo "lzip -dc" ;;
        *.lzma)     echo "unlzma -c" ;;
        *.xz)       echo "xzdec" ;;
        *)          echo "cat" ;;
    esac
}

lesspipe_file() {
    local out=$(file -L -- "$1")
    local suffix
    case ${out} in
        *" 7-zip archive"*) suffix="7z";;
        *" ar archive"*)    suffix="a";;
        *" CAB-Installer"*) suffix="cab";;
        *" cpio archive"*)  suffix="cpio";;
        *" ELF "*)          suffix="elf";;
        *" LHa"*archive*)   suffix="lha";;
        *" troff "*)        suffix="man";;
        *" script text"*)   suffix="sh";;
        *" shared object"*) suffix="so";;
        *" tar archive"*)   suffix="tar";;
        *" Zip archive"*)   suffix="zip";;
        *": data")          hexdump -C -- "$1"; return 0;;
        *)                  return 1;;
    esac
    lesspipe "$1" ".${suffix}"
    return 0
}

lesspipe() {
    local match=$2
    [[ -z ${match} ]] && match=$1

    local DECOMPRESSOR=$(guesscompress "$match")

    # User filters
    if [[ -x ~/.lessfilter ]] ; then
        ~/.lessfilter "$1" && exit 0
    fi

    local ignore
    for ignore in ${LESSIGNORE} ; do
        [[ ${match} == *.${ignore} ]] && exit 0
    done

    case "$match" in

    ### Doc files ###
    *.[0-9n]|*.man|\
    *.[0-9n].bz2|*.man.bz2|\
    *.[0-9n].gz|*.man.gz|\
    *.[0-9n].lzma|*.man.lzma|\
    *.[0-9][a-z].gz|*.[0-9][a-z].gz)
        local out=$(${DECOMPRESSOR} -- "$1" | file -)
        case ${out} in
            *troff*)
                # Need to make sure we pass path to man or it will try
                # to locate "$1" in the man search paths
                if [[ $1 == /* ]] ; then
                    man -- "$1"
                else
                    man -- "./$1"
                fi
                ;;
            *text*)
                ${DECOMPRESSOR} -- "$1"
                ;;
            *)
                # We could have matched a library (libc.so.6), so let
                # `file` figure out what the hell this thing is
                lesspipe_file "$1"
                ;;
        esac
        ;;
    *.dvi)      dvi2tty "$1" ;;
    *.ps|*.pdf) ps2ascii "$1" || pstotext "$1" || pdftotext "$1" ;;
    *.doc)      antiword "$1" || catdoc "$1" ;;
    *.rtf)      unrtf --nopict --text "$1" ;;
    *.conf|*.txt|*.log) ;; # force less to work on these directly #150256

    ### URLs ###
    ftp://*|http://*|*.htm|*.html)
        for b in links2 links lynx ; do
            ${b} -dump "$1" && exit 0
        done
        html2text -style pretty "$1"
        ;;

    ### Tar files ###
    *.tar|\
    *.tar.bz2|*.tar.bz|*.tar.gz|*.tar.z|\
    *.tar.lz|*.tar.tlz|\
    *.tar.lzma|*.tar.xz)
        ${DECOMPRESSOR} -- "$1" | tar tvvf -;;
    *.tbz2|*.tbz|*.tgz|*.tlz|*.txz)
        lesspipe "$1" "$1".tar.${1##*.t} ;;

    ### Misc archives ###
    *.bz2|\
    *.gz|*.z|\
    *.lz|\
    *.lzma|*.xz)  ${DECOMPRESSOR} -- "$1" ;;
    *.rpm)        rpm -qpivl --changelog -- "$1" ;;
    *.cpi|*.cpio) cpio -itv  /dev/null ; then
            dpkg --info "$1"
            dpkg --contents "$1"
        else
            ar tv "$1"
            ar p "$1" data.tar.gz | tar tzvvf -
        fi
        ;;

    ### Filesystems ###
    *.squashfs)   unsquashfs -s "$1" && unsquashfs -ll "$1" ;;

    ### Media ###
    *.bmp|*.gif|*.jpeg|*.jpg|*.ico|*.pcd|*.pcx|*.png|*.ppm|*.tga|*.tiff|*.tif)
        identify "$1" || file -L -- "$1"
        ;;
    *.avi|*.mpeg|*.mpg|*.mov|*.qt|*.wmv|*.asf|*.rm|*.ram)
        midentify "$1" || file -L -- "$1"
        ;;
    *.mp3)        mp3info "$1" || id3info "$1" ;;
    *.ogg)        ogginfo "$1" ;;
    *.flac)       metaflac --list "$1" ;;
    *.torrent)    torrentinfo "$1" || torrentinfo-console "$1" || ctorrent -x "$1" ;;
    *.bin|*.cue|*.raw)
        # not all .bin/.raw files are cd images #285507
        # fall back to lesspipe_file if .cue doesn't exist, or if
        # cd-info failed to parse things sanely
        [[ -e ${1%.*}.cue ]] \
            && cd-info --no-header --no-device-info "$1" \
            || lesspipe_file "$1"
        ;;
    *.iso)
        iso_info=$(isoinfo -d -i "$1")
        echo "${iso_info}"
        # Joliet output overrides Rock Ridge, so prefer the better Rock
        case ${iso_info} in
            *$'\n'"Rock Ridge"*) iso_opts="-R";;
            *$'\n'"Joliet"*)     iso_opts="-J";;
            *)                   iso_opts="";;
        esac
        isoinfo -l ${iso_opts} -i "$1"
        ;;

    ### Encryption stuff ###
    *.crl) openssl crl -hash -text -noout -in "$1" ;;
    *.pem) openssl x509 -hash -text -noout -in "$1" ;;

# May not be such a good idea :)
#   ### Device nodes ###
#   /dev/[hs]d[a-z]*)
#       fdisk -l "${1:0:8}"
#       [[ $1 == *hd* ]] && hdparm -I "${1:0:8}"
#       ;;

    ### Everything else ###
    *)
        case $(( recur++ )) in
            # Maybe we didn't match due to case issues ...
            0) lesspipe "$1" "$(echo $1 | LC_ALL=C tr '[:upper:]' '[:lower:]')" ;;

            # Maybe we didn't match because the file is named weird ...
            1) lesspipe_file "$1" ;;
        esac

        # So no matches from above ... finally fall back to an external
        # coloring package.  No matching here so we don't have to worry
        # about keeping in sync with random packages.  Any coloring tool
        # you use should not output errors about unsupported files to
        # stdout.  If it does, it's your problem.

        # Allow people to flip color off if they dont want it
        case ${LESSCOLOR} in
            always)                   LESSCOLOR=2;;
            [yY][eE][sS]|[yY]|1|true) LESSCOLOR=1;;
            [nN][oO]|[nN]|0|false)    LESSCOLOR=0;;
            *)                        LESSCOLOR=0;; # default to no color #188835
        esac
        if [[ ${LESSCOLOR} != "0" ]] && [[ -n ${LESSCOLORIZER=code2color} ]] ; then
            # 2: Only colorize if user forces it ...
            # 1: ... or we know less will handle raw codes -- this will
            #    not detect -seiRM, so set LESSCOLORIZER yourself
            if [[ ${LESSCOLOR} == "2" ]] || [[ " ${LESS} " == *" -"[rR]" "* ]] ; then
                LESSQUIET=true ${LESSCOLORIZER} "$1"
            fi
        fi

        # Nothing left to do but let less deal
        exit 0
        ;;
    esac
}

if [[ -z $1 ]] ; then
    echo "Usage: lesspipe "
elif [[ $1 == "-V" || $1 == "--version" ]] ; then
    Id="cvsid"
    cat 
             (with plenty of ideas stolen from other projects/distros)


    EOF
    less -V
elif [[ $1 == "-h" || $1 == "--help" ]] ; then
    cat 

        lesspipe specific settings:
          LESSCOLOR env     - toggle colorizing of output (no/yes/always)
          LESSCOLORIZER env - program used to colorize output (default: code2color)
          LESSIGNORE        - list of extensions to ignore (don't do anything fancy)

        You can create per-user filters as well by creating the executable file:
          ~/.lessfilter
        One argument is passed to it: the file to display.

        To use lesspipe, simply add to your environment:
          export LESSOPEN="|lesspipe %s"

        Run 'less --help' or 'man less' for more info
    EOF
elif [[ -d $1 ]] ; then
    ls -alF -- "$1"
else
    recur=0
    [[ -n ${LESSDEBUG} ]] \
        && lesspipe "$1" \
        || lesspipe "$1" 2> /dev/null
fi
2
  • Yes that works. However I have to manually create the folder. I was looking for an automated solution. In windows, winrar has option "extract to" a folder which has the name as the rar file
    – mahmood
    Commented Apr 5, 2013 at 15:19
  • You were waiting for me to finish it, weren't you? :D Commented Apr 5, 2013 at 15:40
1

You can usually use the -C switch to redirect the output of your archive file. I also like to use the -v switch so the output is shown so I know what's going on.

tar xvf archive.tar -C ../1

http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .