Find notes

From Noah.org
Revision as of 19:20, 22 July 2008 by Root (talk | contribs)
Jump to navigationJump to search


exec versus xargs

You may notice that some people will pipe `find` output into `xargs`, but other people tell `find` to start a command using -exec. What is the difference? The difference is that xargs is faster. It will intelligently group arguments and feed batches to the subcommand, so it doesn't have to start a new instance of the subcommand for every argument.

Generally I find -exec easier to use because you can easily repeat the found filename in the exec argument. It's easier for me to express exactly what I want to be executed. Of course, some people think the `find` syntax is wacky. The `xargs` command comes in handy in other places such as a stream not generated by `find`, but when using `find` I stick with -exec unless I have a good reason not to.

You can always do it in a shell loop too:

  for filename in *.png ; do convert $filename `basename $filename .png`.jpg; done

Delete old files with find and cron

Put in /etc/cron.daily. This automatically deletes Spam older than 30 days from my Spam folder.

#!/bin/sh
find /home/vpopmail/domains/noah.org/noah/Maildir/.Spam/cur/ -type f -mtime +30 -exec rm -f {} \;

More CPU efficient:

#!/bin/sh
find /home/vpopmail/domains/noah.org/noah/Maildir/.Spam/cur/ -mtime +30 | xargs rm

copy user permissions to group permissions

find . -exec /bin/sh -c 'chmod g+`ls -ld "{}" | cut -c2-4 | tr -d "-"` "{}"' \;

List all extensions in the current directory

This came in handy when I was trying to find out exactly what mime-types I need to care about.

find . -print0 | xargs -L 1 -0 basename | sed -e "s/.*\(\\.\\s*\)/\\1/" | sort | uniq > /tmp/types

The -print0 option tells find to null-terminate filenames. The -0 option for xargs tells it to read null-terminated strings. These two options are used to handle filenames that have special characters such as quotes or line-feeds. If you don't do this then you may get the following error:

xargs: unmatched single quote; by default quotes are special to xargs unless you use the -0 option

massive recursive grep

When using `grep` with `find` you usually want the -H option, which prints the filename along with the match.

find . -exec grep -H TestToFind {} \;