If you've ever misplaced a file, this month's Command and Conquer is just what you need. There's a bounty of graphical search tools out there, but why use a GUI when you can use the command line!

The first command we'll look at is grep. Grep is used for searching for a specified string within a file. For example, if I had a plain text file called cookies.txt with a recipe for making cookies in it, and wanted to find how many eggs I needed, I could do:

$ grep eggs cookies.txt

This will give a list of all lines that contain the word 'eggs'. As a more realistic example, say I had a configuration file (I'll use apache as an example here, though it could be anything) and wanted to change the name of the error log. Just knowing that it is in the file is no use, I need to know what line number to look at so I can change it.

# grep errorlog /etc/apache2/apache2.conf

Notice that I'm root when running this command. You may be able to run this command as your normal user, depending on the permissions for your configuration file. Try running it as a normal user first! You will notice that this command gives no output. This is because grep is case sensitive.

# grep -n ErrorLog /etc/apache2/apache2.conf

Using -n will make grep give line numbers, so you can find what line the directive is on. Notice that I have changed the capitalization of ErrorLog in this example. You could also use the -i option to make grep ignore case. You can also search all the files in a directory using -r:

$ grep -ir eggs recipes/ 

would find all recipes containing eggs in my recipes directory. What if you want to search by file name? This is where find comes in.

$ find recipes/ -type f -name '*.jpg' 

This will find all the files (-type f) with a name ending in .jpg. Notice how I have enclosed *.jpg in single quotes? This prevents your shell from expanding the *. Try the following, and notice the difference.

$ echo *
$ echo '*' 

The first should give a list of all the files in your current directory, while the second should give *. While find on its own may not seem that useful, when coupled with xargs it becomes a very powerful tool.

$ find recipes -type f -name '*-cake.txt' | xargs -I % cp % old-recipes/ 

This command takes the output of “find recipes -type f -name '*-cake.txt'”, then pipes (|) it into xargs. Using -I % tells xargs to replace % with each line it receives.

$ find recipes -type f -name '*-cake.txt'
recipes/chocolate-cake.txt
recipes/cheese-cake.txt
recipes/fairy-cake.txt

If that (above) is the output, then these are the commands xargs will run:

$ cp recipes/chocolate-cake.txt old-recipes/
$ cp recipes/cheese-cake.txt old-recipes/
$ cp recipes/fairy-cake.txt old-recipes/

If you have a lot of files that match a certain pattern, this can be a very useful method to automate tasks such as a selective backup. If the output of find should be appended to the end, then you can remove -I % and it will be appended automatically to the end of the command. The final command that we'll cover in this issue is locate. Locate might not be installed, so you may need to install it before it works. Locate is a very fast way of finding files with a certain file name. If you have apache installed, try the following:

$ locate apache 

A huge list of files will fly past, so it might be useful to combine its output with grep to find exactly what you're looking for.

$ locate apache | grep etc 

This will narrow down the results to show only those containing 'etc'.

назад