2

Here's what I'm trying to do

find . -maxdepth 1 -type d -print0 | xargs -0 -P4 find -name 'war' -type d

I would like to create a list of directory names, null-terminated, and then pass this list to xargs, which for each directory name calls find using a pool of 4 processes.

My problem is: How do I access stdin in the piped-to find command? Something like

find <STDIN> -name 'war' -type d
  • 3
    You can use -I SOME_SYMBOLS parameter for xargs to construct find SOME_SYMBOLS -name ... but you can do what you want by 1 find command only. – Costas Nov 5 '14 at 10:37
  • @costas I know I could use 1 find for this but I would like to process the directories in parallel. – helpermethod Nov 5 '14 at 10:44
0

use this:

find . -maxdepth 1 -type d -print0 |
xargs -0 -I {} -P4 find "{}" -name "war" -type d

better way is exclude . path:

find . -maxdepth 1 -not -path .  -type d -print0 |
xargs -0 -I "{}"  find "{}" -name "war" -type d
|improve this answer|||||
  • I'd suggest to use -mindepth 1 instead of -not -path .like Anton suggested. Otherwise great answer. – helpermethod Nov 5 '14 at 11:59
  • If you use the output of xargs -P4 then you need to address mixing of output. See example of the problem gnu.org/software/parallel/… – Ole Tange Nov 9 '14 at 19:28
3

Find cannot read its path from stdin, you cannot specify - like with many other programs.

I recommend that you use GNU parallel to run things in parallel:

find . -mindepth 1 -maxdepth 1 -type d -print0  | parallel -0 --jobs 4 \
    find {} -name "war" -type d

Please note the added -mindepth 1 to the first find. If you don't include that, the current directory (.) will be passed in to one of the finds as well and you will get double results.

$ mkdir a b c d e
$ mkdir b/war c/war
$ find . -mindepth 1 -maxdepth 1 -type d -print0  | parallel -0 --jobs 4 \
    find {} -name "war" -type d
./b/war
./c/war
$ find . -maxdepth 1 -type d -print0  | parallel -0 --jobs 4 \
    find {} -name "war" -type d
./c/war
./b/war
./c/war
./b/war
|improve this answer|||||
  • I'd like offer find ./* -maxdepth 0 -type d -print0 instead -mindepth 1 – Costas Nov 5 '14 at 13:53
  • @Costas That would skip directories with a name starting with . unless you take special precautions for the expansion. – Anthon Nov 5 '14 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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