cygwin - Find & du to calculate total size vs xargs
2014-07
Can someone confirm that the following one liner will produce the total human readable size of all the directories which FIND locates as having log in the name?
find -type d -name *log* | du -hcs
Ready?
find . -type d -name '*log*' -print0 | xargs -0 du -hcs
- Wrap the
*log*
in single quotes or else the shell will expand it beforefind
sees it. - Use
-print0
to separate the find output by null characters forxargs
- use
xargs -0
to put each null-separated filename fromfind
into the command line ofdu
Easy, right? :)
$ 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.
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.
Why not just find {a,b,c}.h d e.h -name '*.h'
?
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
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