Fun with the Unix/Linux find command!

This article lists some of the more useful ways of utilizing the find command.

These commands will work on most Linux distributions, and have been tested on recent versions of Ubuntu and SUSE.

To find a file by its name, starting in the current directory and recursing through its children, use:

find . -name '<string>'

Search Inside Files

To search inside files, descending into subdirectories and listing ONLY the file names:

find . -print0 | xargs -0  grep '<search_phrase>' -sl

The above command will print out the names of the files that contain the <search_phrase>, which could be a regex.

Note that the above command works even with “funny” filenames that contain spaces or newlines. The “print0” and -0 option to xargs do the trick – you can see the xargs man page for an explanation of why this works!

Also, xargs is a faster option to the “exec” option of the find command, which is present in many examples on the Internet – though exec is more “portable” across Linux distributions, old and new.

To make things easier for me, I have created a function for the above command, by adding the following line in the /etc/bash.bashrc file at the bottom:

function f() { find . -print0 | xargs -0 grep "$1" -sl; }

Try it out – your search term can even contain regular expressions! Here’s an example usage:

f SOAP

will search for the word “SOAP” in all files starting recursively from the current directory.

Finding Files Based on Permissions

To find files that match a certain permission, use the perm option:

find . -perm -644

will match all files that have, at a minimum, the rw permission set for user AND r permission for group AND r permission set for others.

find . -perm 644

will match all files that exactly have the rw permission set for user AND r permission for group AND r permission set for others.

find . -perm /644

will match all files that have the either the r or w permission set for user OR r permission for group OR r permission set for others.

To find files writable by the current user, use:

find . -writable 

Other tricks

On similar lines to the find+grep combination above, you can use xargs to perform other tasks, such file deletion or text replacement. For example, to delete the files found by find, use:

find . -name '<string>' -print0 | xargs -0 rm

To replace contents of multiple files at once, you can use find along with sed. The following command will search for files containing the number 12121 and replace it with 99999:

find . -print0 | xargs -0 grep '12121' -sl | xargs sed -i 's/12121/99999/g'

The sed command above searches for the 1st string and replaces it with 2nd string. The g option is for global replacement, or else only the 1st occurence will get replaced. The -i option will make changes in the same file, in place.



Comments

I like the .bashrc function! I put it in .bash_aliases though.
Thanks.

Me too - I've put them in .bash_aliases. I didn't mention this in the article because I noticed other distributions do not use that file.

By Abdullah Chougle

It would be nice if you proofread your article; looking into the code makes it even more obscure what was meant. ('<string>'</string>, '<search_phrase>' -sl</search_phrase>, and <search_phrase>. </search_phrase>)? Additionally, 644 is hardly rwxr--r--.

If not too confusing, this article would have been interesting for an aspiring find novice like me.

By Anonymous

Thanks for pointing it out ... it seems like these errors crept it in during some last minute editing.

By Abdullah Chougle

All right then! This looks better, thanks for editing.

By Anonymous

grep -R 'regex/phrase' dir

xargs is only faster, if you run a program that supports multiple arguments. A depressing number of applications does not.
By Awebb

You are right. Avoiding xargs with find is good. we can use -exec in find command

You can get the speed advantage of xargs without the need for the extra process and the pipe I/O overhead by using find -exec and terminating the command with a '+' instead of a ';':

find . -exec grep -sl -- 'search phrase' {} +

By Anonymous

Add new comment