I am searching for some folders in my current directory. What I want to do is, move all the files within those directories to another directory. I am using the following command:

find -maxdepth 1 -regex 'myRegexExpHere' | xargs -I file mv file/* Desktop/New\ folder/

But as expected, the '*' is not expanded by xargs, instead searching for a file named * in each folder. What should I do to achieve my aim? Please suggest ways involving the use of xargs only (and not the -exec switch of find), primarily because I have read that using xargs is much more efficient.

  • find -exec … + is even more efficient than xargs. And further, it probably doesn't matter—the moves themnselves will most likely be the vast majority of the time.
    – derobert
    Nov 12, 2013 at 22:44
  • Yeah, I guess I will have to resort to -exec if I don't get any other solution. Besides, as you said, the move part is the major time-hogger, so it probably doesn't matter.
    – Parag Goel
    Nov 13, 2013 at 6:41

2 Answers 2


You need the expansion of the wildcard to happen in a shell that's executed after file has been replaced by the name of the matching file. So you need to start a shell from xargs.

Better than using xargs, use the exec predicate to find. It's simpler and doesn't suffer from quoting issues.

find -maxdepth 1 -regex 'myRegexExpHere' -exec sh -c 'mv "$0"/* Desktop/New\ folder/' {} \;

You're probably overcomplicating things. This simple use of find can be expressed directly in most shells. Ksh has a syntax for regular expressions:

  • @(EXPR1|EXPR2) matches EXPR1 or EXPR2
  • *(EXPR) matches 0 or more occurrence of EXPR
  • +(EXPR) matches 1 or more occurrence of EXPR
  • ?(EXPR) matches 0 or 1 occurrence of EXPR

This syntax is also available in bash if you run shopt -s extglob first, and in zsh if you run setopt ksh_glob first. Then you can use

mv REGEX/* Desktop/New\ folder/

Why use find when you don't need recursion? Use the shell (I'm assuming Bash here, modify to suit your needs) for regex matching:

for dir in */;do
    if [[ "$dir" =~ yourRegexHere ]];then
        mv -- "$dir"/* "Desktop/New folder/"

If your shell's regex capabilities are too weak for your requirements, it doesn't get any better than Perl:

perl -e 'for(grep {/yourRegexHere/} glob "*/"){ 
             qx(mv -- "$_"/* "Desktop/New folder") 
  • So I should always try to use a loop when I need to perform such operations? What are the cases then where a single command would benefit me?
    – Parag Goel
    Nov 13, 2013 at 6:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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