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 want to examine a directory and execute a command for each matching folder. The following find correctly returns the list I'm looking for.

find . -maxdepth 1 -name "*.bitbucket"

For each item returned, I want to execute the command:

hg pull --update --repository [FIND_RESULT_HERE]

Is there a simply way to do this using find and xargs? If not, what's the best alternative.

share|improve this question
2  
The option -depth means to process files first instead of dir, and it doesn't take any arguments. Maybe -maxdepth? –  Darksair Jun 3 '11 at 16:02
    
@Darksair Thanks! You people (StackExchangers) are great; makes me proud to be a member of a community that is so genuinely helpful (and exceptionally smart). –  Robert Altman Jun 4 '11 at 22:29

3 Answers 3

up vote 4 down vote accepted

Use the -exec option for find like this:

find . -maxdepth 1 -name "*.bitbucket" -exec hg pull --update --repository {} \;

The {} gets replaced with the find result and the \; terminator indicates that they should be executed one at a time. A + would cause a bunch of them to be strung together as arguments.

share|improve this answer
    
I've always used \{\} thinking it would cause a bash expansion. Why doesn't bash expand {} in this case? –  Deepak Mittal Jun 3 '11 at 20:31
    
Never mind. Found the answer –  Deepak Mittal Jun 3 '11 at 20:34
    
Because it's empty, there is nothing to expand. Bash and other shells only expand things they recognize can be made into something else. That very fact is what makes it perfect for find's argument replacement system. It's unlikely to be part of a normal commands arguments because it's a nonsense expansion, but can be recognized and replaced with the file matches. –  Caleb Jun 3 '11 at 20:35
    
Makes sense. Thanks :) –  Deepak Mittal Jun 3 '11 at 20:38

@Caleb's answer is good. Or you can do it with xargs.

If you want to do the hg thing for each find results, (as @Caleb's pointed out,)

find . -depth 1 -name "*.bitbucket" | xargs -n1 hg pull --update --repository

If you want to accumulate all find results into one command, remove the -n1.

Also, be careful about -depth. This option does not use any argument. I think you mean -maxdepth.

share|improve this answer
1  
This is actually incorrect, xargs can be used to execute things one by one using -n1 as an argument. The real problem with xargs here is how it handles quoting arguments. It can be a nightmare to get it right, where using find … -exec … {} just takes care of it. –  Caleb Jun 3 '11 at 16:04
    
Thanks for pointing out the -n1 option. However I don't understand your point about quoting arguments. If you worry about spaces in filenames, --delimiter "\n" can be used. –  Darksair Jun 3 '11 at 16:18
find . -maxdepth 1 -name "*.bitbucket" -execdir hg pull --update --repository {} +

will process multiple files in parallel. Not every find might have an -execdir; Gnu/find suggests using it to avoid errors.

share|improve this answer

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.