Linux: Harnessing The Über-Powerful Find Command (+xargs)

By Daniel Miessler on October 10th, 2006: Tagged as Linux | Sysadmin
  • Name Required

    you should mention how to redirect the permission denied messages

    find / -name required 2> /dev/null

  • Artifex

    It might also be good to mention the standard technique for using find with tar.

    find . -daystart -mtime 0 > temp tar -cvf stuff.tar -T temp rm temp

    Generally you don’t want to use xargs with tar and the create (c) flag, unless your sure that there are only a very few files.

  • http://dmiessler.com Daniel Miessler

    Ah, great comments; thanks!

  • http://gen-sec.blogspot.com/ Dave

    Excellent stuf!

  • http://del.icio.us/links Lenny

    I don’t think the following command-line from your article:

    # Clean the images off of your *nix desktop
    find ~/Desktop -name "*.jpg" -o -name "*.gif" -o -name "*.png" -print0 | xargs -0 mv ~/Pictures 
    

    will work as you expect. You’ll want to wrap the find(1) -name tests in parentheses, otherwise you’ll only list the *.png files.

    Also, the mv(1) command(s) that xargs(1) will generate, won’t work because the last argument needs to be a directory. Assuming your Desktop directory looks like this:

    $ ls Desktop Pictures
    Desktop:
    bar.png  foo.gif  one.png  three.jpg  two.jpg
    
    Pictures:
    

    here’s the results of running your original command-line:

    $ find Desktop  -name "*.jpg" -o -name "*.gif" -o -name "*.png"  -print0 | xargs -0 -t mv Pictures
    mv Pictures Desktop/bar.png Desktop/one.png 
    mv: when moving multiple files, last argument must be a directory
    Try `mv --help' for more information.
    

    Here’s a version that will work as you expect:

    $ find Desktop  \( -name "*.jpg" -o -name "*.gif" -o -name "*.png" \) -print0 | xargs -0 -t mv --target-directory=Pictures
    mv --target-directory=Pictures Desktop/three.jpg Desktop/two.jpg Desktop/foo.gif Desktop/bar.png Desktop/one.png
    
    $ ls Desktop Pictures
    Desktop:
    
    Pictures:
    bar.png  foo.gif  one.png  three.jpg  two.jpg
    

    IIRC the –target-directory option is specific to the GNU version of mv(1).

    If you had a standard mv(1) command lacking the –target-directory option, you’d need to move one file at a time and xargs wouldn’t provide much benefit over the -exec feature of find(1):

    $ find Desktop  \( -name "*.jpg" -o -name "*.gif" -o -name "*.png" \) -print0 |  xargs -0 -t -i mv {} Pictures
    mv Desktop/three.jpg Pictures
    mv Desktop/two.jpg Pictures
    mv Desktop/foo.gif Pictures
    mv Desktop/bar.png Pictures
    mv Desktop/one.png Pictures
    
    $ ls Desktop Pictures
    Desktop:
    
    Pictures:
    bar.png  foo.gif  one.png  three.jpg  two.jpg
    

    The -t option to xargs(1) is your friend. It traces the commands generated by xargs(1). If you want to be extra cautious, use -p instead and it will print each command-line and ask you if you want to proceed.

blog comments powered by Disqus

Original Content


Trending

Popular

Information Security / Technology

Politics

Philosophy & Religion

Technology & Science

Culture & Society

Miscellaneous


Discovered Content

Top Blog Categories