views:

65

answers:

5
#!/bin/sh
#My script

echo "Are you sure you want to reorganize your files?"
echo "Type y or Y to continue. Anything else will stop the process"
read response

if [ "$response" = "y" ] || [ "$response" = "Y" ]; then
  mkdir video
  mkdir audio
  mkdir text
  mv -v *.txt text >> log.txt
  mv -v *.wmv video >> log.txt
  mv -v *.mov video >> log.txt
  mv -v *.mpg video >> log.txt
  mv -v *.mp3 audio >> log.txt
  mv -v *.wma audio >> log.txt


  echo "Yay, it worked!"
else
echo "Nothing happened."
fi

I wrote the script above to organize files into subfolders. For instance the music files will go into an audio folder. Now I would like to take a step further and make it more global.I would like to allow the script to accept a command line argument, which is the folder that contains the unorganized files. This should allow the script to be located and run from anywhere in the file system, and accept any folder of unorganized files.

Example:

organizefiles.sh mystuff/media // subfolders would go inside "media"

the folder media contains all of the media files.

Thank you!

+1  A: 

You can refer to the command line parameters as $1, $2, etc. The first one is $1. Here's a good description of how to pass arguments to a script: http://docsrv.sco.com:507/en/OSUserG/_Passing_to_shell_script.html

Kaleb Brasee
+1  A: 

Scripts has access to arguments on the command line via some variables like this:

$1, $2, ..., $n - refers to first, second up to n arguments.

Example: Typing myscript.sh foo will set foo to the $1 variable.

Vincent Ramdhanie
in which part of my script do I add those variables?
jualin
SOURCE_DIR=$1 # at the top of the file, then check it exists.
Mark Byers
like this:#!/bin/bashsource = $1mkdir moviesmv -v $source/*.wmv movies >> log.txtmv -v $source/*.mov movies >> log.txt
jualin
+1  A: 

Bash arguments are fairly straightforward, using a $# format. So for example, you could access the first argument of the command line from your script with $1

In your script, you could do something like so:

if [ -z $1 ]
then
   dir = $1
else
   dir = './'
fi

Then just add the new $dir variable to the paths in your mv commands. I recommend checking out Bash By Example from IBM. A great article series to teach you Bash.

Note that there may be a petter better to do what I suggested but I am nowhere near an expert in Bash. :-)

Bartek
Thank you for the link!
jualin
+1  A: 

A portion of your script could use the first positional parameter like this:

if [ -d $1 ]
then
    mkdir video
    mkdir audio
    mkdir text
    mv -v $1/*.txt text >> log.txt
    mv -v $1/*.wmv video >> log.txt
    mv -v $1/*.mov video >> log.txt
    mv -v $1/*.mpg video >> log.txt
    mv -v $1/*.mp3 audio >> log.txt
    mv -v $1/*.wma audio >> log.txt
else
    echo "The destination directory does not exist"
    exit 1
fi
Dennis Williamson
I get "destination directory does not exist" when I try to use it
jualin
Did you put that between your "if $response" line and the "echo Yay" line? Did you run your script as `organizefiles.sh mystuff/media`? Does "mystuff/media" exist? Actually, Now that I look at your question again, I think you want to move **from** $1 so I've edited my answer accordingly.
Dennis Williamson
thank kyou i will try it right now.
jualin
test.sh: 16: [[: not foundThe destination directory does not existThat's the error I got.
jualin
I'm sorry, you're using the Bourne shell instead of Bash. Try it with `[ -d $1 ]` - I've edited my answer.
Dennis Williamson
Thank you it worked great!
jualin
there's no need to use 3 mkdir --> mkdir video text audio
ghostdog74
what if $1 is being used in another portion of the code and he wants to use the directory name again somewhere also in that portion? Its always advisable to name argument variables to some meaningful name.
ghostdog74
Also, I am not the one using this code, the OP has to modify to suit his need if he wants to consolidate the mkdirs or not or reuse an argument, therefore I don't answer to solve EXACTLY his problem. **grin**
Dennis Williamson
+1  A: 

here's a simple system. you can use case/esac instead of if/else for neatness. also, rearranged the mv commands a bit

#!/bin/bash
dir=$1
cd $dir
while true
do
    echo "Are you sure you want to reorganize your files?"
    printf "Type y or Y to continue. Anything else will stop the process: "
    read response
    case "$response" in 
        y|Y ) 
            mv -v *.txt text >> log.txt
            for vid in "*.mov" "*.wmv" "*.mpg" "*.wma"
            do
                mv $vid video >> log.txt
            done
            echo "yay"
            break;;
        *) echo "Invalid choice";;
    esac
done
ghostdog74
So "N" is an "Invalid choice"? You either need a `break` in your default case or you need an `n|N` case (and change the wording of your prompt) unless you're *not going to take "no" for an answer*. Also you can just `cd $1` - you don't need the $dir variable.
Dennis Williamson
I don't want to break because I want to ask the user response again. Also, I am not the one using this menu, the OP has to modify to suit his need if he wants to break or not, therefore I don't answer to solve EXACTLY his problem. I just want to name $1 to $dir, what's the problem?? It looks english to me and maybe i want to use $dir again in my code , and i don't want to conflict with another $1 in my loop for example??
ghostdog74