I am new to bash script and want to create bash script that moves some days old files between source and destination as per days defined in script.

When I run this script I get error

find: paths must precede expression: mv Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]


echo "Enter Your Source Directory"
read soure

echo "Enter Your Destination Directory"
read destination 

echo "Enter Days"
read days

   find $soure -mtime +$days  mv $soure $destination {} \;

  echo "Files $days old moved from $soure to $destination"

What's missing or wrong ???? please help me to create this script.

  • As an fyi, bash scripting usually falls under StackOverflow... since that's where coders hang out... – Thomas Ward Dec 20 '12 at 11:26
  • 1
    mv is a command , not an argument .The way you have written mv is taken as an argument of find.You either need it to be passed through -exec argument or pipe (|) the results from find to mv – Mevin Babu Dec 20 '12 at 11:49
  • Mevin's comment is correct. You should also quote your "$variables" before spaces in paths cause you trouble. – Trent Nelson Jul 7 '17 at 13:13

I'm sure you've already come across them already, but the two best places to begin with learning bash scripting are the Bash Guide for Beginners and the Advanced Bash-Scripting Guide. If you haven't seen these two resources yet, I would highly recommend bookmarking them if you're looking to do further bash scripting.

Removed portion regarding flow control due to edit in question. The find command needs -exec before the command or else it won't know that mv is actually a command you're attempting to execute on the files. Also, the {} in the find is used to refer to the results of the find command, thus you won't need $source as part of the find. The find command would probably look more like:

find $source -mtime +$days -exec mv {} $destination \;

If the find results will include files/directories with spaces in them, then you may need to loop through the results (which will bring the do/done back into the mix) so that you can include the results of the find in a variable that can then be enclosed in quotes. That will give a structure similar to the following:

for result in $(find $soure -mtime +$days)
    mv "${result}" $destination

If you're still having problems, I'd suggest including a copy of your terminal window from running the script. Also, try running just the find command by itself without the -exec mv... portions and replacing the variables with what you'd normally fill in for them during the script execution. That way you can get an idea as to what the find command is matching so you can be certain that it's matching the files you want it to before making any changes to the location of your files.

  • Thank You.... Are pdf versions are available of above guides ??? – KK Patel Dec 20 '12 at 12:09
  • There may be PDF versions, but I've never checked, always preferring to read them directly online. – Matrix Mole Dec 20 '12 at 12:13

I think you need to have a for statement before the do loop, in order for it to work. Look here, for more information on Bash loops.

  • I don't need loop I want just simple script – KK Patel Dec 20 '12 at 11:03
  • 2
    In that case, it should work if you remove the do & done statements. – Neojames Dec 20 '12 at 11:14
  • No problem! Glad I could help! – Neojames Dec 20 '12 at 11:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.