Monthly Archives: October 2016

Find… and Exec

In the last two posts, we talked about finding things. The result of that find command was a list of filenames or directory names… just lists of things. Which is useful if we want to know ‘where did I leave that file’. But I want to do things with these files. Suppose I want to know when all files that have an ‘s’ in them were last accessed. I could do that by finding all of those files and then doing ls -l on each one. But I’m lazy, I don’t want to do that.

As I’ve said many times, there’s more than one way of doing things in Linux. You can do things the long and complicated way or you can learn a little about the command line and do things the short and fast way. Let’s talk about that short and fast way and get to the end result. I’m lazy. I don’t want to type the same thing over and over again. Luckily, find lets me get away from that. See?

find . -name '*s*' -exec ls -l {} \;

So I’m finding all files that have an s in them, just like I’ve done before. Now, though, I’m adding a new flag, -exec. After that flag, I give the command I want. The {} means take the output of the find and put that value in those brackets. So it’s going to do ls -l on every file it finds.

One command to take care of all those commands I listed before, isn’t that neat?

Now let’s pretend I want to rid my system of all sith. Those sith infested my system with lots of files, all of them with the name sith (or some variant thereof) and I’ve got to get rid of them.

find / -iname '*sith*' -exec rm {} \;

So I find any file with the name sith or Sith or DarthSith or SithofDarkness or even sItH… and I remove them. All go away and I don’t even need to find my lightsaber.

Finding More Things

find has lots and lots and LOTS of flags. Lots. So we’re going to see what other cool things we can do with it.

So last post, we talked about finding Sewers. Suppose I forgot if it’s Sewers or sewers or SEWERS or even sEwErs. I know the name, I just forgot what case I used. Luckily, there’s a flag for that.

Alpha:~ computerlamp$ find . -iname sewers

See how I used iname as my flag rather than name? That means ignore the case of what I’m looking for. If the name is Sewers or SeWeRs or sewerS… or any other combination, this command will find it. I can also look for anything with an ‘S’ in it either upper case or lower case by doing:

Alpha:~ computerlamp$ find . -iname '*s*'

Suppose I want to know all the files in my home directory, no matter where I’ve put them. I want to find them, in other words. Well, guess what… find has a flag for that.

Alpha:~ computerlamp$ find . -type f

The flag -type has a flag. A flag with a flag. Or a flag with a smaller flag. The first flag means ‘find everything with a certain type’. The second flag means ‘and that type is a file’. If you said:

Alpha:~ computerlamp$ find . -type d

Guess what? You’re looking for all directories. And there’s even a subflag for symlinks. That’s:

Alpha:~ computerlamp$ find . -type l

You can combine these flags. I want all directories that have an s in their name:

Alpha:~ computerlamp$ find . -type d -name '*s*'

Or I can look for all symlinks that have the name word in them.  find has approximately a gazillion flags, just check out the man page for it if you don’t believe me.   For example, there’s even a flag for finding any files that are empty.  empty is that flag.  In other words:

Alpha:~ computerlamp$ find . -empty

In summary:  find has a flag for that.

I’ve lost my files, how can I find them?

We’ve talked about finding things in files and using grep and more to do that, let’s talk about finding files. I’ve lost my file and I can’t look through my file until I find my file.

And that’s what the command Linux® uses to find files is called. find. How’s that for imaginative naming? We’re going to find with find.

Let’s begin by cd‘ing into our home directory. Remember we can do that just by typing cd.

We want to find that file blog1.txt we created a while back. We know it exists, we know we put it somewhere, but we forget where. (It was in the home directory but let’s pretend otherwise for right now.) We tell find to start in the home directory and look for a file named blog1.txt. This is done by:

Alpha:~ computerlamp$ find . -name blog1.txt

See that ‘.’ after find? That’s really important. That tells find to start in the directory you’re in and look from there. The flag ‘-name’ tells the command ‘look for the file with this name’.

We can do other neat things. Suppose we know the file we’re looking for ends with the letters txt but we’ve forgotten if it started with blog, or blogg, or maybe bloggo, or even MyBlog. But we know it ends with txt, so that’s a start! In this case, we can do this command:

Alpha:~ computerlamp$ find . -name '*txt'

See that asterisk? That tells find to match any file that ends with txt and starts with anything else. It could be blog or bloggo, but it could even be thisfile.txt. Or turtles.txt. Or turtles-in-txt. It can match all of those and find will return every single one.

We can also find directories with find. Remember that Sewer directory we made a while back? find will find that as well:

Alpha:~ computerlamp$ find . -name Sewer

We can also use find to look into the sewer.

Alpha:~ computerlamp$ find Sewer

I didn’t give it a name flag that time. That means it’ll look into that directory and find whatever is in there.

 

Symlinks … or how to be lazy.

We’ve been using the file /usr/share/dict/words in the past posts to look up words. We can use this to figure out if we’ve spelled things correctly, for example, looking for freind only to discover that it isn’t in the file. Oops, it’s spelled friend.

Every time we look up a word, we have to type /usr/share/dict/words. Over and over and… What we want is a shortcut to that file, so we don’t have to type the whole thing repeatedly. The shortcuts in Linux® are called symlinks, also known as symbolic links. The command to create them is ln and we create the symlnks as:

Alpha:~ computerlamp$ ln -s target destination

Where target is the file (or directory) we want to create a shortcut to and destination is our shortcut. So for example:

Alpha:~ computerlamp$ ln -s /usr/share/dict/words words

Will create a shortcut to /usr/share/dict/words as words in the current directory. You can more (or less) words, grep words, and generally treat it like any other file. If we want to remove it when we’re done or no longer need it, we can just use the command rm.

One other thing to note about it: If you use the command ls -F, you’ll see words@. The @at the end of the filename is your only sign that it’s a symlink. Otherwise, if you do just a plan ls, you’ll see words without any sign that it is a symlink. It’s just another file.

Back to creating the link. There’s no rule that says I had to link the file named words to a new file named words. I could have called it something else. Like:

Alpha:~ computerlamp$ ln -s /usr/share/dict/words heapbigwordlist

Or even:

Alpha:~ computerlamp$ ln -s /usr/share/dict/words thematrix

It’s nice how Linux® lets us be lazy.  I don’t want to type the entire path to the dictionary file out, I’ll just make a symlink.  And the symlink is a file, so I can treat it like one.

Finding words in files… take two!

In the last post we discussed how to find a word in the file /usr/share/dict/words using more.  This being Linux®, there’s always another way to do it.  This way uses the command grep. Jumping right to an example, try this:

Alpha:~ computerlamp$  grep way /usr/share/dict/words

This returns every single word in the file /usr/share/dict/words that contains way.  As in the last post, we’re looking for words that begin with way, not any word that contains way. We can find those words using:

Alpha:~ computerlamp$  grep ^way /usr/share/dict/words

This returns every word that begins with way.  When I tried it, I got 48 words.  How many do you get?

grep is case specific. This means that if you tell it to find way, it won’t find Way or wAy or waY. It matches precisely what you give it. As luck would have it, we don’t have to grep for every possible combination of case. There’s a flag for that. We can use the flag -i to ignore the case. That means, match every possible case when looking for the word way. For example:

Alpha:~ computerlamp$  grep -i ^way /usr/share/dict/words

That finds every possible word that begins with way, no matter what case it has in the file.

How, what happens when you look for a string in a command?  Can I grep grep?

Let’s try it:

Alpha:~ computerlamp$  grep test /usr/bin/grep

I got nothing back.  So it didn’t fail, but it didn’t work.   That’s because the command grep is a binary, which means there’s generally no text in it.

Now let’s try something else!  Suppose we want to find all strings in the file that don’t match our string.   So following our example, we want all strings in /usr/share/dict/words that don’t have the string way in them.  In this case, we do:

Alpha:~ computerlamp$  grep -v way /usr/share/dict/words

If you do this,  you get a lot of results.  An awful lot of results.

 

 

More on more (and less)

In the Linux® system, there is a fle that contains a list of dictionary words. This file is normally in /usr/share/dict/words. Each line on that file contains a single word. If you want to know how many words are in the file, try:

Alpha:~ computerlamp$  wc -l /usr/share/dict/words

Wow, isn’t that a lot of words in a single file?  The one on my system has 235,886 words.  That’s a lot.

Now imagine using more (or less) on the file and looking for a single word. This could take forever. Especially if we’re looking for vulcan because we want to make sure we spelled it right. There has to be an easier way to find this… And of course there is. If we are using more (or less) to look through the file, then we can use the . Try

Alpha:~ computerlamp$ more /usr/share/dict/words

and hit the key. Then type the word you’re looking for and it will hopefully take you to it.  Try that with turtle.  Now pretend we tried to page through the file looking for turtle.  We’d still be looking.

Now suppose we’re looking for the word way. If we type that, the command takes is to the word airway. Which is almost, but not quite, what we need. I could keep looking through the file, but that would give me every word that had way in it.  Like alway, or away or backway or cartway.  There’s an awful lot of words with way in it.

We need to tell more that we’re looking for the word that begins with way. We can do this by typing ^way (see the ^) which tells more that the word should begin with way. Now if the word isn’t found in the file, then… either you spelled it wrong (vulcan begins with a v not a w!) or it doesn’t exist in the file.  For example, google isn’t in my file!

And that’s how you find words in your files.