Thursday, February 23, 2012

bash parameter parsing from data

I had to write a script where parameters are read form a shell script. At first I thought writing a shell function to extract values would be nice and if it could allow shell syntax and quoting that would also be nice so here it is:
get_param() {
    local paramname="$1"
    local result=""

    local IFS="
"
    for line in $SCRIPT_DATA; do
        unset IFS
        line=${line%%#*} # removed any comments
        case "$line" in
        *"$paramname"=*)
            # lets check we are not matching only suffix of param
            case `echo ${line%%=*}` in
            $paramname) result=`eval "$line ; echo \"\\${$paramname}\""` ;;
        esac
        ;;
        esac
    done
    echo -n "$result"
}

if SCRIPT DATA is like:
param1=value1
hostname=`hostname`
paramN=valueN


get_param hostname would return the hostname of machine.

If SCRIPT_DATA is like:
hostname='`hostname`'

get_param hostname would return `hostname` avoiding expansion.

A couple of limitations:
  • control structures are not regarded
  • not secure (run only through trusted code)
  • multi-line expressions not supported
After all I decided complexity isn't worth it so just source/eval the script data. If necessary use grep/sed to filter it.
Maybe it would have been more useful if I could split the script data to complete shell expressions but I'm not sure added complexity will be worth it either.

In any case I just put this function here to not lose it. Similar use cases pop from time to time...

Saturday, February 4, 2012

batch convert to MP3

I've got a car MP3 player and immediately found out all my music is in various formats and it's a pain to copy something over to the player with the correct format.
Searching the net didn't show something reasonable for mass/batch/bulk converting files to mp3, at least not something that would really make the job easier. So I thought it's time for some bash again.
Here I have a script that given a list of sources which can be directories and files and a destination will go over known music files in sources and copy them to the destination with their relative paths preserved *AND* converted to MP3.
Conversion is performed by playing the file through mplayer which feeds pcm audio data to the lame mp3 encoder stdin. So a wide range of input formats are supported even video files where the first audio stream is processed.

Usage:
./cp2mp3.sh <src1> ... <srcN> <dst>


For example if you have:
$ find
./file1.flac
./dir1/file2.ogg
./dir2/dir3/file3.wav
./dir4/dir5/file4.avi
and run:
./cp2mp3.sh file1.flac dir1 dir2 dir4/dir5 <somedir>
you will end up with:
$ cd <somedir>
$ find
./file1.mp3
./dir1/file2.mp3
./dir2/dir3/file3.mp3
./dir5/file4.mp3


Script may need some small modifications depending lame or mplayer locations, lame/mplayer settings, additional file extensions might be necessary, stuff like that, but generally I think its ready to use.


Download it from here and let me know how it works for you. And before I forget again, file is licensed under GPLv3.