You are not logged in.

#1 2011-12-03 12:39:12

xr4y
Member
Registered: 2011-05-06
Posts: 33

Passing arguments to case

Hi, I am trying to run this script as follows;

avplaylist -a Music/artist/
or
avplaylist -v Videos/tv_show/

and have it create a sorted playlist for me. It works if I make one function for audio and one for video but not this way, what am I doing wrong?

#!/bin/bash

caser() {
    while read i; do
        case "$i" in
            "$1") echo "$i" >> "$3" ;;
        esac
    done < <(find "$2" -name "*" | sort)
}

lister() {
    if [ -e "$1" ]; then
        cat "$1" | wc -l
    else
        echo 0
    fi
}

case "$1" in
    -v) 
        caser "*.mov|*.avi|*.mp4|*.flv|*.wmv|*.MTS|*.mpeg|*.mpg|*.mkv" "$2" "videoplaylist"
        lister "videoplaylist"
        ;;

    -a) 
        caser "*.wav|*.aif|*.aiff|*.wma|*.mp3|*.ac3|*.flac|*.ogg" "$2" "audioplaylist"
        lister "audioplaylist"
        ;;
esac

Thanks in advance!

Offline

#2 2011-12-03 13:01:59

roygbiv
Member
Registered: 2011-05-18
Posts: 204

Re: Passing arguments to case

I think the $1, $2, ... $n varibles are reserved for the command-line arguments given to the script itself, so these do not change throughout the execution.
Edit: I'm not sure if that's the problem here though. Yes, my bad..

Last edited by roygbiv (2011-12-03 13:30:34)

Offline

#3 2011-12-03 13:24:48

xr4y
Member
Registered: 2011-05-06
Posts: 33

Re: Passing arguments to case

roygbiv, the $1,$2..$n are not reserved for the command-line when you call functions as above, at least that is my understanding.

The problem seems to be when I try to pass "*.mov|*.avi|*.mp4|*.flv|*.wmv|*.MTS|*.mpeg|*.mpg|*.mkv" as an argument, since this version works:

#!/bin/bash

vcaser() {
    while read i; do
        case "$i" in
            *.mov|*.avi|*.mp4|*.flv|*.wmv|*.MTS|*.mpeg|*.mpg|*.mkv) echo "$i" >> "$2" ;;
        esac
    done < <(find "$1" -name "*" | sort)
}

acaser() {
    while read i; do
        case "$i" in
            *.wav|*.aif|*.aiff|*.wma|*.mp3|*.ac3|*.flac|*.ogg) echo "$i" >> "$2" ;;
        esac
    done < <(find "$1" -name "*" | sort)
}

lister() {
    if [ -e "$1" ]; then
        cat "$1" | wc -l
    else
        echo 0
    fi
}

case "$1" in
    -v) 
        vcaser "$2" "videoplaylist"
        lister "videoplaylist"
        ;;

    -a) 
        acaser "$2" "audioplaylist"
        lister "audioplaylist"
        ;;
esac

Passing of $1,$2..$n variables works just fine in this version!

Offline

#4 2011-12-03 20:31:50

rockin turtle
Member
From: Montana, USA
Registered: 2009-10-22
Posts: 227

Re: Passing arguments to case

Try this:

#!/bin/bash

video=(mov avi mp4 flv wmv MTS mpeg mpg mkv)
audio=(wav aif aiff wma mp3 ac3 flac ogg)

getfiles () {
	dir="$1" && shift
	for f in "$@"; do
		find "$dir" -name "*.$f";
	done;
}

dir='.'
[[ "$1" =~ ^- ]] && av="$1" && shift
[[ $# -gt 0 ]] && dir="$1"

case "$av" in
	-a) playlist=$(getfiles "$dir" "${audio[@]}" | sort); ofile="audioplaylist" ;;
	 *) playlist=$(getfiles "$dir" "${video[@]}" | sort); ofile="videoplaylist" ;;
esac

[ -n "$playlist" ] && echo "$playlist" > "$ofile"
[ -n "$playlist" ] && wc -l <<< "$playlist"
[ -z "$playlist" ] && echo 0

It defaults to video files if you don't give a -a or -v  switch, and it defaults to the current directory if you don't provide a directory.

Offline

#5 2011-12-03 21:14:18

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

Re: Passing arguments to case

And if you want to handle files with whitespace or any metacharacters, none of this works...

#!/bin/bash

video=(mov avi mp4 flv wmv MTS mpeg mpg mkv)
audio=(wav aif aiff wma mp3 ac3 flac ogg)

usage() {
  printf 'usage: %s <-a|-f> [directory]\n' "${0##*/}"
}

populate_playlist() {
  while read -rd '' file; do
    playlist+=("$file")
  done < <(for f in "${@:2}"; do find "$1" -name "*.$f" -print0; done | sort -z)
}

while getopts ':ahv' flag; do
  case $flag in
    a) files=("${audio[@]}"); ofile=audioplaylist ;;
    h) usage; exit 0 ;;
    v) files=("${video[@]}"); ofile=videoplaylist ;;
    *) echo "error: invalid option -- '$OPTARG'"; exit 1 ;;
  esac
done
shift $(( OPTIND - 1 ))

(( ${#files[*]} )) || { usage; exit 1; }

populate_playlist "${1:-.}" "${files[@]}"

(( ${#playlist[*]} )) && printf '%s\n' "${playlist[@]}" > "$ofile"
echo "${#playlist[*]}"

Offline

#6 2011-12-03 21:52:54

rockin turtle
Member
From: Montana, USA
Registered: 2009-10-22
Posts: 227

Re: Passing arguments to case

And if you want to handle files with whitespace or any metacharacters, none of this works...

@falconindy, I assume you meant this about the script I posted. I believe that it does work for filenames that don't contain \n or \r (or perhaps \v).

Is that what you mean when you say it won't handle whitespace, or is there something else I don't understand?

You realize, of course, that any filename that contains a \n will show up as two files in the destination file anyway.

Offline

#7 2011-12-04 14:59:27

xr4y
Member
Registered: 2011-05-06
Posts: 33

Re: Passing arguments to case

Thanks alot rockin turtle and falconindy. There are parts in your scripts that are totally new to me, more tools in the box eventually.

Offline

Board footer

Powered by FluxBB