Thursday, April 26, 2012

Basic find

This is to remind me of how to use the Unix command find. Possibly only I will find this useful. I'm just "indexing my head."

Make a test directory with one file:

> cd ~/Desktop
> mkdir x
> touch x/y.txt
> cd

Basic usage for find is: find dirname -name filename

> find . -name y.txt
./Desktop/x/y.txt
>

Don't forget the -name. Without it, find thinks file_name is just another place to search, since find can take multiple directories to search. "." is, of course, the current directory (I'm in my home directory "~"), while "/" would be the root of the file system.

Another use would be to count the number of files with wc:

> find . | wc -l
  158479
>

Of course, find can use wildcards.

> find ~/Desktop -name \*.txt
/Users/telliott/Desktop/notes.txt
/Users/telliott/Desktop/todo.txt
/Users/telliott/Desktop/x/y.txt

Notice the backslash to escape: \*

[ UPDATE: Can also be done with quotes "*.txt" ]

The above will also find hidden files. Other useful options for find include:

-type
-mtime
-mmin


For example, find all recently changed files:

> find ~/Desktop -mmin -30
/Users/telliott/Desktop
/Users/telliott/Desktop/.DS_Store
/Users/telliott/Desktop/.y.txt
/Users/telliott/Desktop/x
/Users/telliott/Desktop/x/y.txt

Do this with ~ to find where TextEdit saves all its data about the current state!

With appropriate caution, you might pipe the results to xargs to run a command:

> cd Desktop/
> find . -name \*.txt
./.y.txt
./notes.txt
./Rob Pike.txt
./todo.txt
./x/y.txt
> find . -name \*.txt | xargs /bin/ls -al
ls: ./Rob: No such file or directory
ls: Pike.txt: No such file or directory
-rw-r--r--  1 telliott  staff    0 Apr 26 06:23 ./.y.txt
-rw-r--r--@ 1 telliott  staff   29 Apr 23 15:54 ./notes.txt
-rw-r--r--@ 1 telliott  staff  815 Apr 24 17:19 ./todo.txt
-rw-r--r--  1 telliott  staff    0 Apr 26 06:00 ./x/y.txt

Notice what happened to the filename that contains a space. I have to read more to know how to fix that.

If you're searching the system without read permission for directories you'll get error messages:

> find / -name foo
find: /.DocumentRevisions-V100: Permission denied
find: /.fseventsd: Permission denied
find: /.Spotlight-V100: Permission denied
find: /.Trashes: Permission denied

They can be discarded like this:

> find / -name foo 2>/dev/null

This redirects stderr (the "2") to /dev/null, which is a Unix black hole.

Another sort of listing is obtained with du-disk usage, piped to sort and then to tail.

> du -sc * | sort -n | tail
1590728 My Downloads
3188512 Software
3392024 Dropbox
8421800 VirtualBox VMs
8509928 Library
8937696 Teaching
19995376 Pictures-TE
43919360 Music
236592936 Movies
336685360 total

Learn Unix in 10 minutes (quick reference)
A nice reference for find (and other stuff).