2

I usually use the find command to automatically copy certain multimedia files from directory A to directory B. I use the following command:

for f in `find ./ -name "*.mkv" -mtime -24h`; do cp $f rename/ ; done

This totally does what I want, but now that I have transferred the command into an executable script (let's call it mmcopy, it works perfectly) I wonder whether I could improve the script to do the following:

When I type mmcopy on the command line, I would like to parse two operators/variables to the script, namely a variable of the file extension and a variable to the mtime operator, so I can specify which kind of files should be copied and how old these files may be.

E.g.: I want to automatically copy (all) .jpg files in a directory that are newer than 3 days, the commandline should look like mmcopy jpg -3d

How would I have to change my script in order to be able to so?

Georg
  • 21
  • If you call your script with mmcopy jpg -3d then you can use the variables $1 and $2 in your script, which will expand to jpg and -3d respectively. These variables are called positional parameters. – Ernest A Mar 22 '15 at 18:29

1 Answers1

2

First, your current script breaks on file names containing whitespace and other special characters. It's very easy to fix this: always use double quotes around variable substitutions, and use -exec instead of parsing the output of find. See Why does my shell script choke on whitespace or other special characters? for more information.

find . -name "*.mkv" -mtime -24h -exec cp {} rename/ \;

Arguments passed to your script are available in the special parameters $1, $2, etc. Here's a script that copies files whose extension is the first parameter to the script and whose timestamp comparison is given by the second parameter.

#!/bin/sh
find . -name "*.$1" -mtime "$2" -exec cp {} rename/ \;

If you want to assume default values if the arguments are missing, you can use the ${…:-…} parameter expansion construct.

#!/bin/sh
find . -name "*.${1:-mkv}" -mtime "${2:--1d}" -exec cp {} rename/ \;

I recommend replacing cp by cp -p or rsync -a. cp -p preserves the timestamp on the file, which makes it easier to tell when you've already copied a file. rsync -a additionally doesn't copy the file if it's already been copied (unless the original file has a different timestamp or size).