Home Classroom Linux Basics Linux Basics Part 8

Linux Basics Part 8

1066

Searching files in Linux

In our Linux basics series so far we have discussed a few areas ranging from the command line or GUI basics to basic administrative topics such as package management.

Modern Linux distributions tend to provide user friendly graphical interfaces comparable to anything available in other operating systems. For example if you consider the current or the upcoming releases of popular distributions like Ubuntu, Fedora, Mint and openSUSE, you will notice that they are very much in the same high quality GUI scale as Apple MacOS X or Microsoft Windows 7. In future articles we plan to discuss more and more graphical tools and tips as we move on. For today however we are planning to give you some tips about a command line tool which can impress your friends.

When you are working in a command line how would you locate a file or a directory? In a GUI you could browse the directories using a file browser or execute a search tool. Would you be surprised that you could search and locate files/directories in a Linux systems with ease using only command line tools, perhaps even better than GUI tools?

New Command: find

The command find is a traditional Unix command you would find in almost all Linux systems. Despite is simple name, the command is a very powerful tool. The price of that power is that the usage of find can be a little daunting for a new user. Perhaps in the past you have tried to use the command and failed or it didn’t give the intended output. Today we take control and learn a few things about find.

Find by the name

Let us have a look at the syntax of the basic find usage. It’s like:

The find has the ability to conduct searching based on many different criteria. For example let us search our home directory to find any files with the “.mkv” extension. If you remember the previous sessions, then you might recall that in Linux a file extension is just another part of the file name. So we are about to run a search based on the file name.

$ find where/to/look what-to-look-forThe find has the ability to conduct searching based on many different criteria. For example let us search our home directory to find any files with the “.mkv” extension. If you remember the previous sessions, then you might recall that in Linux a file extension is just another part of the file name. So we are about to run a search based on the file name.

Eg:
$ find ~ -name *.mkvLet us try to understand the above example in detail. First of course you know we are running the find command. The we give “~” as the location where to search for. Again if you recall previous sessions, “~” character refers to your home directory.

Then comes the curious part where we tell the find command the criteria of our search. By using “-name” option we tell it to base the search on the file name. As the name pattern we give “*.mkv” which means a name with any number of characters before the ending 4 characters which are “.mkv”.

Once significant thing to mention here is that our search patterns are case sensitive. Which means the above search will find a file named “Avatar.mkv” but not a file named “Avatar.MKV”. The reason is we are saying our search pattern is “*.mkv” not “*.MKV”.

What if we want to find the files with a certain pattern, regardless of the case (Upper, lower or mixed). In such a case (which is quite often) you have to use the option “-iname” instead of “-name”.

Now that you have a firm grasp of that, let try to find the same files inside your current directory.

Eg:
$ find . -iname *.mkv As you might have correctly remembered the “.” notation here is a shorten way of referring to the current directory. In the same sense you can use “..” instead of “.” to search in the parent directory of the current directory.

The where to look does not have to be one of those characters. For example we could tell find to search in the /tmp/play directory by

Eg:
$ find /tmp/play -iname *.mkv I case you were wondering, you can give multiple search paths as well in the find command.

Eg:
$ find . /tmp /usr/share/doc -iname *postgres*.pdfIn the above example we are telling find to search inside the current directory, “/tmp” and “/usr/share/doc” with the characters “postgres” in anywhere in the name and ending with “.pdf”.

As you can see, you can search anywhere in the file system where you have permission. This means that certain directories are not readable for regular users. In such as base you have to use find in conjunction with a command like “sudo” or “su -c” or else run it while logged in as the user “root”.

So far all the above examples are searching for a pattern in the file name. What if you want to search based on the file creation date, last accessed date or the file size.

At this point I am pretty sure that you won’t be surprised to know that “find” can do that too.

Find by the type

Now let us run a search to find only files. Which means directories matching the search pattern will not be included in the results. The option to search for the type is “-type”. So to search for files only we can give “-type f”.

Eg:
$ find . -type f -iname ubuntu*The above example will search the current directory for any files (no directories) with a name starting from the characters (case insensitive) “ubuntu”.

There are other different types that you can include in your search criteria. Simply use the relevant type character after the “-type” option.

f - regular file
d - directory
s - socket
l - symbolic link
If you don’t understand these types yet, that could because we have not talked about them yet. So no need to panic. If you somehow know them, then you can go ahead and give it a try.

Find by the time

Eg:
$ find . -type f -mtime 7 -iname *.odt The above example will search the current directory for any files (no directories) with a name ending with “.odt” which has been modified during the past 7 days. The “-mtime” option specifies the last modified time. If you need to use the last accessed time rather than the last modified time, then you can use the “-atime” option

Both “-atime” and “-mtime” takes the next parameter in days (i.e. 24 hours). So as in previous example “-mtime 7″ means last modified date is within 7 days (or 168 hours). What if you need to make these time based searched by minutes instead of days?

For those cases there are two similar options named “-amin” and “-mmin” which acts the same as “-atime/-mtime”, but only with minutes as in the following example.

Eg:
$ find . -type f -mmin 10 -iname *.odt

Find by the permissions

In the coming articles we can talk about the Linux security model with details including about the file permissions and ownership, etc. As for now it is enough to let you know that the find command has the ability to run searching based on file permissions too.

Eg:
$ find . -perm -o=wThe above example however asks find to look in the current directory for any file or directory where the “world/other” have write permission. If this does not make much sense to you, do not worry. We can discuss permissions later.

Find by the size

Another useful criteria when you are searching for things is the file size. In the real life application, a server configuration file or a word processed document should be much noticeably smaller in size than a video file of a full movie. As you can see when these kind of distinctions are possible, you can always use the “-size” option with parameters. Let us consider an example.

Eg:
$ find . -size 1024kThe above example will search the current directory for files with the exact size of 1024 kilobytes (i.e. 1 megabyte). Now what if we want to search all files larger than 1 gigabyte?

Eg:
$ find . -size +1GAs you can see in the above example we are asking find to look for anything larger than one gigabyte. What if we want to find something smaller than a particular size?

Eg:
$ find . -size -10M Yes, you guessed correctly. The above example will search for anything smaller in size than 10 megabytes. If you were wondering which are the character notation to specify the units we are going to use (Eg: megabyte, gigabyte, etc.), here are a few.

c - bytes
k - kilobytes
M - megabytes
G - gigabytes
Those four are not the only ones available, but those are the most commonly used ones as you can guess.

In the same lines you can easily search for empty files.

Eg:
$ find . -size 0c

Find by the owner

Apart from the above talked criteria, there is also the ability to run searches based on the owner of the file. Again the ownership and group ownership are two things we shall be discussing in a future article. For now you can assume that each and every file has an owner.

So to get back to the topic, we can ask find to search files/directories based on the ownership of a file by using the “-user” option with a user parameter.

Eg: $ find . -user gaveen

The above example will search the current directory for things owned by the user named “gaveen”.

Advanced: Perform operations based on the results

If you think the fun gets over there, you were wrong. Our friend “find” can also be utilized in many creative and advanced ways. However without straining you ming let us get to an example. Remember, it is just one of the things possible with find.

Eg:
$ find . -iname *.png -exec cp {} ~/test/ \;

Since the above example is more advanced than what we have already discussed, let us go through it carefully. First, part of the command might be familiar to you. Consider what is there from the beginning until the part “*.png”. As you might remember it is in fact searching for all files ending with the “*.png” inside the current directory.

Then there is this curious “-exec” option, which opens a whole new world of opportunities. Basically “-exec” executes some command we provide against the results of the first part of the find command. In this case we are asking to copy (using the cp command) the results of the first part of the find command into the directory located at “~/test”.

Let us examine the exec part more carefully. It says, execute cp with the destination location of “~/test”. The pair of curly braces acts as a place holder for the results from the first part of the command. So you must be catching this up gradually. But why the “\;” part?

When “-exec” runs a command, it runs the command for each single result. Which means if there are 25 results found by the first part, the cp command will run 25 times. Consider the “\;” as a break sequence which tells the “-exec” that the commands ends there. So the command completes by that sequence.

Hint: Common error message with find

One of the most common error message you would see with the find command is: “find: paths must precede expression”. This is annoying because after some rigorous rechecking of your command that you can be sure that it is correct. But it would not execute. For example if could be something like this.

Eg: $ find . *.rpm

The problem here is the shell getting confused by the “*” mark in the name pattern we entered. Here is the solution. Use “\” as an escape character for the “*”.

Eg: $ find . \*.rpm

It is good practice to escape special characters anyway in the Linux command line, even if it is not mandatory. In this case however it could be mandatory.

Congratulations if you have come this far. Now you know a fair amount about how to use find properly; one of the most underutilized commands in Linux/Unix which is also a very powerful command. Before we wrap up todays article let us combine some the options we discussed into an advanced find command.

Eg: $ find /tmp -type f -iname fedora*.iso -size +3G -mtime 300 -exec cp {} ~/test/ \;

What the above command is supposed to do is search for files (only) with a name starting with “fedora” and ending with “.iso” which are over 3GB in size and have a last modified date within 300 days, ans then copy them into the directory located at “~/test”.

Well, that is just about what we have to say about the find command today. You let me know if that last command is correct or not.

Comments

comments

Gaveen is a Linux System Administrator with several years of industry experience and is a strong FOSS promoter. He is pending graduation from University of Wolverhampton and also holds a certification from Red Hat. He also conducts Linux trainings with Red Hat training partners. Being highly enthusiastic about computing, he supports a keen interest in Ruby programming too. When not distracted by his wide range of interests including reading, music, cricket, etc.,he regularly blogs at Gaveen's Blog

NO COMMENTS

Leave a Reply