Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
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 '13 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 '13 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/
share|improve this answer

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/"
    fi
done

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") 
         }'
share|improve this answer
    
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 '13 at 6:42

Your Answer

 
discard

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.