0
$ echo {a,b,c}.h d e.h |xargs -IA find A -name '*.h'
find: `a.h b.h c.h d e.h': No such file or directory
$ echo -e a.h\\nb.h c.h d e.h |xargs -IA find A -name '*.h'
a.h
find: `b.h c.h d e.h': No such file or directory

The problem is that -I implies xargs will assume arguments are delimited by newline. I'm not sure why that is. I reckon I can solve this problem with sed, but I wonder if there's an xargs trick or idiom I'm not familiar with that people use to solve this.

I'm looking for a solution that will also work on OS X. On OS X the xargs -J switch seems to work fine. The manpage claims this switch will just control where the arguments are placed for the executable -- which is exactly what I want.

4 Answers 4

0

Hmm. Do you need the pipe and xargs? It seems like all your example really needs is the find and the echo.

I'm guessing this is a piece of a larger puzzle, so this may not work in the context of what you're doing, but your example could be written as:

$ find `echo {a,b,c}.h d e.h` -name '*.h'

$ find $(echo {a,b,c}.h d e.h) -name '*.h'

... which, on my system, results in find checking each argument individually:

find: `a.h': No such file or directory
find: `b.h': No such file or directory
find: `c.h': No such file or directory
find: `d': No such file or directory
find: `e.h': No such file or directory

I don't have an OSX machine to test with, and these may be bash-specific.

2
  • My original intent was to have the list of directories and files coming from stdin. I'll have to do with one of the workarounds. I'm still curious why -I implies delimiting by newline though. Feb 7, 2010 at 20:40
  • give it time, someone else might have a real answer for you. i thought maybe you needed the expansion, not the stdin. Feb 7, 2010 at 20:50
0

Why not just find {a,b,c}.h d e.h -name '*.h'?

2
  • see his comment on my answer; he needs the argument list coming from stdin. (good simplification of my answer, at least in the example find+echo case.) Feb 7, 2010 at 21:28
  • Ok, if you need the list coming from stdin, then you must try to do one of the following: 1. Don't use spaces in directory names, and then pipe things through sed -e 's/\s+/\n/g'; 2. Find a way to separate the incoming directory names by newlines or nulls, and then use either xargs --null find ... or while read x; do ... ; done. Feb 9, 2010 at 16:58
0

did you try the -d option to xargs?

justin@eee:~$ echo {a,b,c}.h d e.h |xargs -d ' ' -n1  -IA echo foo A
foo a.h
foo b.h
foo c.h
foo d
foo e.h

or even simpler,

justin@eee:~$ for x in $(echo {a,b,c}.h d e.h);do echo foo $x;done
foo a.h
foo b.h
foo c.h
foo d
foo e.h
2
  • -I implies ignoring -d. Besides, -d takes exactly one character as argument. You can't have arbitrary whitespace as delimiter. That is, in terms of regex it's / / but you can't do /\s/ or even /\s+/. Feb 8, 2010 at 1:42
  • works fine for me, see my comment. If this still isn't what you want, you are going to have to give a better example that shows what you are really trying to do.
    – user23307
    Feb 8, 2010 at 5:14
0

Use GNU Parallel:

parallel -q find {} -name '*.h' ::: {a,b,c}.h d e.h

Watch the intro video to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .