3

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.

  • 2
    The option -depth means to process files first instead of dir, and it doesn't take any arguments. Maybe -maxdepth? – MetroWind Jun 03 '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 04 '11 at 22:29

3 Answers3

4

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.

Caleb
  • 70,105
  • I've always used \{\} thinking it would cause a bash expansion. Why doesn't bash expand {} in this case? – Deepak Mittal Jun 03 '11 at 20:31
  • 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 03 '11 at 20:35
0
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.

user unknown
  • 10,482
-1

@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.

MetroWind
  • 237
  • 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 03 '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. – MetroWind Jun 03 '11 at 16:18