cygwin - Find & du to calculate total size vs xargs

07
2014-07
  • Tony

    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
    
  • Answers
  • cxw

    Ready?

    find . -type d -name '*log*' -print0 | xargs -0 du -hcs

    • Wrap the *log* in single quotes or else the shell will expand it before find sees it.
    • Use -print0 to separate the find output by null characters for xargs
    • use xargs -0 to put each null-separated filename from find into the command line of du

    Easy, right? :)


  • Related Question

    How do I execute find with GNU xargs to traverse a set of directories?
  • wilhelmtell
    $ 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.


  • Related Answers
  • quack quixote

    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.

  • Ryan Thompson

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

  • user23307

    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
    
  • Ole Tange

    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