You are not logged in.

#1 2010-12-24 09:48:12

graysky
Wiki Maintainer
From: :wq
Registered: 2008-12-01
Posts: 10,645
Website

More elegant way to create a smarter "extract" function in my .bashrc

I picked up the "extract" function somewhere and added it to my ~/.bashrc.  I want to make it inspect the first dir that it extracts and cd into it upon a successful extraction so I came up with the following:

extract () {
   if [ -f $1 ] ; then
       case $1 in
           *.tar.bz2)   tar xvjf $1 && cd $(echo $1 | sed 's/.tar.bz2//')    ;;
           *.tar.gz)    tar xvzf $1 && cd $(echo $1 | sed 's/.tar.gz//')    ;;
           *.bz2)       bunzip2 $1 && cd $(echo $1 | sed 's/.bz2//')    ;;
           *.rar)       unrar x $1 && cd $(echo $1 | sed 's/.rar//')    ;;
           *.gz)        gunzip $1 && cd $(echo $1 | sed 's/.gz//')    ;;
           *.tar)       tar xvf $1 && cd $(echo $1 | sed 's/.tar//')    ;;
           *.tbz2)      tar xvjf $1 && cd $(echo $1 | sed 's/.tbz2//')    ;;
           *.tgz)       tar xvzf $1 && cd $(echo $1 | sed 's/.tgz//')    ;;
           *.zip)       unzip $1 && cd $(echo $1 | sed 's/.zip//')    ;;
           *.Z)         uncompress $1 && cd $(echo $1 | sed 's/.Z//')    ;;
           *.7z)        7z x $1 && cd $(echo $1 | sed 's/.7z//')    ;;
           *)           echo "don't know how to extract '$1'..." ;;
       esac
   else
       echo "'$1' is not a valid file!"
   fi
 }

Two questions:

1) Is there a more elegant way to code this behavior?
2) I'd like to add the behavior of "[ if -d $i]; then cd $i else exit" where $i is just the filename without the extension that my sed statement makes but again, without adding one line per extension, is there a more elegant way to code this?

Last edited by graysky (2010-12-24 09:49:19)


CPU-optimized Linux-ck packages @ Repo-ck  • AUR packagesZsh and other configs

Offline

#2 2010-12-24 11:32:37

dyscoria
Member
Registered: 2008-01-10
Posts: 1,007

Re: More elegant way to create a smarter "extract" function in my .bashrc

I'm no expert, but you could do something like:

 *.tar.bz2)   tar xvjf $1 && [[ -d ${1%.tar.bz2} ]] && cd ${1%.tar.bz2}    ;;

flack 2.0.6: menu-driven BASH script to easily tag FLAC files (AUR)
knock-once 1.2: BASH script to easily create/send one-time sequences for knockd (forum/AUR)

Offline

#3 2010-12-24 11:51:50

Awebb
Member
Registered: 2010-05-06
Posts: 6,611

Re: More elegant way to create a smarter "extract" function in my .bashrc

By more elegant you mean... written in one line and harder to modify? :-D

Offline

#4 2010-12-24 15:42:18

AugustePop
Member
Registered: 2010-04-27
Posts: 95

Re: More elegant way to create a smarter "extract" function in my .bashrc

i think the more elegant way is putting the cd and related commands after the case switch, or write a wrapper function.

Offline

#5 2010-12-24 15:44:58

SiD
Member
From: Germany
Registered: 2006-09-21
Posts: 729

Re: More elegant way to create a smarter "extract" function in my .bashrc

have a look at unp

Offline

#6 2010-12-24 15:47:32

juster
Forum Fellow
Registered: 2008-10-07
Posts: 195

Re: More elegant way to create a smarter "extract" function in my .bashrc

I would consider using basename a little easier and/or more elegant:

case $1 in
    *.tar.bz2)   tar xvjf $1 && cd $(basename "$1" .tar.bz2) ;;

Last edited by juster (2010-12-24 15:49:47)

Offline

#7 2010-12-24 16:05:56

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: More elegant way to create a smarter "extract" function in my .bashrc

there's no guarantee that the directory extracted is related to the name of the tarball. or that there's a directory at all.

Offline

#8 2010-12-24 16:23:47

wonder
Developer
From: Bucharest, Romania
Registered: 2006-07-05
Posts: 5,941
Website

Re: More elegant way to create a smarter "extract" function in my .bashrc

why scripting such thing when you can use only tar xf tarball?


Give what you have. To someone, it may be better than you dare to think.

Offline

#9 2010-12-30 20:55:55

Bralkein
Member
Registered: 2004-10-26
Posts: 354

Re: More elegant way to create a smarter "extract" function in my .bashrc

Hey I was bored and so I had a stab at this one. Dunno if this is an elegant solution exactly (it seems a bit fiddly) but it seems to do what you asked for without repetition of code.

extract () {
    if [ ! -f "$1" ] ; then
      echo "'$1' is not a valid file!"
      return 1
    fi

    # Assoc. array of commands for extracting archives
    declare -A xcmd
    xcmd=(
      [.tar.bz2]="tar xvjf"
      [.tar.gz]="tar xvzf"
      [.bz2]="bunzip2"
      [.rar]="unrar x"
      [.gz]="gunzip"
      [.tar]="tar xvf"
      [.zip]="unzip"
      [.Z]="uncompress"
      [.7z]="7z x"
    )
    # extension aliases
    xcmd[.tbz2]="${xcmd[.tar.bz2]}"
    xcmd[.tgz]="${xcmd[.tar.gz]}"

    # See which extension the given file uses
    fext=""
    for i in ${!xcmd[@]}; do
      if [ $(grep -o ".\{${#i}\}$" <<< $1) == "$i" ]; then
        fext="$i"
        break
      fi
    done

    # Die if we couldn't discover what archive type it is
    if [ -z "$fext" ]; then
      echo "don't know how to extract '$1'..."
      return 1
    fi

    # Extract & cd if we can
    fbase=$(basename "$1" "$fext")
    if ${xcmd[$fext]} "$1" && [ -d "$fbase" ]; then
      cd "$fbase"
    fi
}

I don't do all that much bash scripting so handle with caution!

Edit: Changed the code - quoted a bunch of stuff so it doesn't break on files with spaces in the name. Told you I don't do much of this!
Edit 2: Nicer way of initialising the assoc array

Last edited by Bralkein (2010-12-31 02:00:33)

Offline

Board footer

Powered by FluxBB