1. Searching for files
-
We can make a quick search for files with
locate
:locate bin/zip
If the search requirement is not so simple, we can combine
locate
with other tools, likegrep
:locate zip | grep bin
locate zip | grep bin | grep -v unzip
-
While
locate
searches are based only on the file name, withfind
we can also make searches based on other attributes of files.It takes as arguments one or more directories that are to be searched:
ls -aR ~
find ~
To find only directories we can use the option
-type d
and to find only files we can use-type f
:find . -type d
find . -type f
find . -type d | wc -l
find . -type f | wc -l
find . | wc -l
-
We can also search by filename and file size:
sudo find /etc -type f | wc -l
sudo find /etc -type f -name "*.conf" | wc -l
We enclose the search pattern in double quotes to prevent shell from expanding "
*
".sudo find /etc -type f -name "*.conf" -size -2k | wc -l
sudo find /etc -type f -name "*.conf" -size 2k | wc -l
sudo find /etc -type f -name "*.conf" -size +2k | wc -l
-2k
matches the files whose size is less than 2 Kilobytes,2k
those who are exactly 2 Kilobytes, and+2k
those who are more than 2 Kilobytes. Besidesk
we can also useM
for Megabytes,G
for Gigabytes, etc. -
find
supports many other tests on files and directories, like the time of creation or modification, the ownership, permissions, etc. These tests can be combined with logical operators to create more complex logical relationships. For example:find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
This looks weird, but if we try to translate it to a more understandable language it means: find on home directory ( files with bad permissions ) -or ( directories with bad permissions ). We have to escape the parentheses to prevent shell from interpreting them.
-
We can also do some actions on the files that are found. The default action is to
-print
them to the screen, but we can also-delete
them:touch test{1,2,3}.bak
ls
find . -type f -name '*.bak' -delete
ls
touch test{1,2,3}.bak
find . -type f -name '*.bak' -print -delete
ls
We can also execute custom actions with
-exec
:touch test{1,2,3}.bak
ls
find . -name '*.bak' -exec rm '{}' ';'
ls
Here
{}
represents the pathname that is found and;
is required to indicate the end of the command. Both of them have been quoted to prevent shell from interpreting them.If we use
-ok
instead of-exec
then each command will be confirmed before being executed:touch test{1,2,3}.bak
ls
find . -name '*.bak' -ok rm '{}' ';'
-
Another way to perform actions on the results of
find
is to pipe them toxargs
, like this:touch test{1,2,3}.bak
ls
find . -name '*.bak' | xargs echo
find . -name '*.bak' | xargs ls -l
find . -name '*.bak' | xargs rm
ls
xargs
gets input from stdin and converts it into an argument list for the given command.