Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm searching for an simple shell script to mv all folders in /var/www/uploads/ that containing Math or Physics in the name to /mnt/Backup/.

I've never done something like that before, due to the fact I am new to shell scripting. Searched across the web and unfortunately I only found scripts for moving specific files. Is there anyone who may help?

share|improve this question
up vote 2 down vote accepted

According to this SO Post: use xargs to mv the “find” directory into another directory
i would use something like :

 find /var/www/uploads/ -type d  \( -name '*Physics*' -o -name '*Math*' \) \
    -exec mv -t /mnt/Backup/ {} +

This will find any directory at any depth in your /var/www/uploads folder and move it to the backup dir.
If you want to limit the search to the first level you can add to find the option -maxdepth 1

find /var/www/uploads/ -maxdepth 1 -type d  \( -name '*Physics*' -o -name '*Math*' \) \  
-exec mv -t /mnt/Backup/ {} +

And if you want to have a case insensitive search you can use the argument -iname instead of -name so it looks like :

 find /var/www/uploads/ -type d  \( -iname '*Physics*' -o -iname '*Math*' \) \
   -exec mv -t /mnt/Backup/ {} +

this will only work with recent versions of GNU or FreeBSD find and mv (-iname, -maxdepth and -t are not standard).

I also use \ to add jumpline in the command line and make it more readable.

Note 2:

If you want have a nice understanding of the command you can try this ExplainShell link

share|improve this answer
@stephaneChazelas why the edit if it's what I want to write ? – Kiwy Feb 20 '14 at 11:03
Yours didn't work as you forgot the -print0. Rather than adding the non-standard -print0, I prefered to fix it by using the standard syntax instead. – Stéphane Chazelas Feb 20 '14 at 11:04
@StephaneChazelas fair enought thanks. – Kiwy Feb 20 '14 at 11:05
Works very well. Thank you for sharing this! :) – SaulGoodman Feb 20 '14 at 12:20

I'd use the unix command find, with the option -d to search for directories only, and tell it to execute the command to move the directory to /mnt/Backup. Instead of using a regexp to do it in one step, I'd simply run the command twice, like this:

find /var/www/uploads -type d -name "*Math*" -exec mv {} /mnt/Backup/ \;
find /var/www/uploads -type d -name "*Physics*" -exec mv {} /mnt/Backup/ \;

If you want to do the same thing for a large number of directory names, so that you don't want to have to repeat names, you can use a variable instead:

for name in Math Physics; do find /var/www/uploads -d -name "*${name}*" -exec mv {} /mnt/Backup/ \;
share|improve this answer
#! /bin/bash
shopt -s extglob
# replace echo with mv when output OK
echo /var/www/uploads/*@(Math|Physics)* /mnt/Backup/
share|improve this answer
could you explain what it does – Kiwy Feb 20 '14 at 10:31
@Kiwy It does exactly what the OP wants, doesn't it? And that's more or less the best description of what is happening. You may search in man bash for "pattern-list". – Hauke Laging Feb 20 '14 at 10:45
I was more curious about the shopt -s extglob option – Kiwy Feb 20 '14 at 10:46
@Kiwy I guess extglob is disabled by default. But (as you would have found at exactly that place in the man page) it is needed to make the @() work (which is called extended globbing). – Hauke Laging Feb 20 '14 at 10:49
Yes sorry, wrong edit. Might be better with echo mv ... and then remove the echo though. – Stéphane Chazelas Feb 20 '14 at 11:28

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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