2003-12-16, 05:52 PM
In Linux whenever you are not sure about the name of a file and you want to do something with files such as either search for them or copy them or delete some files based on some knowledge you have about the filenames then you can use Wildcards. Wildcards are basically an indicator to the shell that some particular part of the filename is not known to you and the shell can insert a combination of characters in those places and then work on all the newly formed filenames. This concept would be clear by the end of this article
There are 3 types of wildcards that can be used Linux. They are the * ? and [] . All the 3 shall be explained in detail.
* (Asterisk) Wildcard
This represents any sequence of characters. This means that if you include a * in your filename then that part of the filename can be formed using any sequence of characters. The example below explains this concept
$ cat article* > combinedarticle
Would find all the files that begin with the letter sequence ' article ' and can have anything following those letters. I mean article01 or article10 or articlenew.. and any such file would be considered. All these files would be merged and would be written to a file named combinedarticle
$ ls *gif
Would list all the files having the letters ' gif ' in them. So a file named somegifs.txt as well as a file named 123.gif would be listed in the output.
$ ls *.gif
Would list all the files having ' gif ' as the extension of their filename. Thus in this case a file named somegifs.txt file would NOT be listed since its extension is not ' gif '. Whereas a file named 123.gif would be listed.
$ ls *day*
Would list all the files that have the letters ' day ' anywhere in their filenames. Thus files such as today.txt , dayone.txt and lastday.gif would all be listed in the output.
$ ls .*gif*
Would list all the hidden files in the current directory that have the letters ' gif ' in their filenames. Hidden files in Linux begin with a . (period) in their filenames.
$ pl * a.txt
Notice that there is a space between the * and ' a.txt ' . It is this space that causes the command to act as if 2 parameters have been passed to ' pl ' rather than one. The above command would print all the files that are present in the current directory. Once that is done it would proceed to the next file named a.txt and would print that also if it exists.
Note : The * would not work with the ' . ' (period) that exists in filenames. Thus in case you use ' *a ' and there is a file whose name begins with ' .a ' , it would not be listed. When a . (period) is the first character in a filename then the file becomes a hidden file in Linux.
-
? (Question Mark) Wildcard
This represents only one character which can be any character. Thus in case you know a part of a filename but not one letter, then you could use this wildcard. If there are many files that are named such as article10, article11 and so on till article19 you could get all these files by using article1? . In this case the ? would be interpreted as any one character and it would find all the files like article10, article11..and so on till article19, since all these files differ in their names by only the last letter.
$ ls article1?
Would list all the files that begin with ' article1 ' and have one more character in their names which can be any one valid character.
$ ls ??.gif
Would list all the .gif files in the current directory that have only 2 characters before the extension. Thus files such as ab.gif or xy.gif would be listed but 123.gif would not be listed
Remember that the ? means any ONE character to be substituted in the place of the ?
$ ls *.???
Would list all the files in the current directory that have a file extension of 3 characters in length. Thus files having extensions such as .gif , .jpg , .txt would be listed.
-
[] (Square Brackets) Wildcard
This represents a range of characters. So in case you have files that are named article10, article11, article12..all the way till article19 then you could select all the first 5 of them using the above wildcard as shown below
$ ls article1[0-4]
Remember that [] represents a range from which any character can be present. This range can be something like [0-4] or [1-9] or anything like that in case of numbers. Letters could also be selected such as [a-g] or [F-Z] or [A-Z].
Note : Remember that in Linux the filenames are case sensitive, Thus a range of [a-z] is different from [A-Z]
$ ls beckham[123].jpg
Would list all the files that begin with the letter sequence ' beckham ' and end with either a 1, 2 or 3. Thus the possible filenames that could be listed (if they exists) are beckham1.jpg , beckham2.jpg and beckham3.jpg
$ ls [a-d,A-D]*.jpg
This would list all the files that have an extension as .jpg and have as their first letter either a,b,c,d,A,B,C or D . The [ , ] imply that this entire range indicates ONLY ONE letter which can be from any of the two given sub-ranges. A comma is used to merge different range of letters or numbers.
Note : I would once again like to mention that [a-d,p-z] does NOT mean that there can be two letters, the first one from a to d and the second one from p to z. It means that there is ONLY ONE letter, and that letter can be from either a to d or from p to z.
In case you want to specify the range for 2 characters in the filenames then use the following as follows
$ ls beckham[0-9][0-9]
Now I shall discuss the use of special characters such as " ' and ` in various commands that you type at the shell prompt. The information given here is general and has to be followed when typing any command.
" " (Double Quotes) : Suppress Expansion
Whenever you use double quotes (" ") the shell suppress the filename expansion. Thus even if you use a wildcard such as * but enclose it within double quotes you would not get the standard feature of matching for all characters. I mean a command such as
$ ls c*
would list all the files with the names beginning with the letter ' c ' . But a command such as
$ ls "c*"
would search for a file named ' c* '. There would be no expansion of the * to match other letter sequences. The shell would expect the filename to have the actual character * in its name. Thus you would mostly get a 'No File Found error' message.
-
` (Back Quotes) : Command Substitution
The ` character (found on the key with the ~) is very important when used in shell commands. This ` indicates that command substitution is required wherever it is used. Hence whenever ` is used, whatever part of the command is enclosed by these Backquotes marks would be executed (as if it was the only command) and then the result of that command would be substituted in the original shell command that you typed. The following explains this clearly
$ echo "The contents of this directory are " `ls -l` > dir.txt
Note : Remember to use the ` (found on the key with the ~ and NOT the one found next to the Enter button)
The above command would basically execute the ' ls -l 'part first and then substitute the result after the string "The contents of this directory are " and both of these together (directory listing + the string) would be written to a file named dir.txt
Basically after command substitution the new substituted value would act as additional parameter to the main command that was present in your initial statement.
-
' (Apostrophe Marks) : No Change
The ' character (found on the button next to the Enter button) is a very powerful character whenever used in any shell command. Basically the ' (apostrophe marks) disables all kinds of transformations or modifications. It would consider whatever is enclosed with the ' marks as a single entity i.e. a single parameter. Absolutely no sort of substitution or expansion would take place.
$ echo '$HOME'
would produce at the output the string $HOME itself and would not print the path to your home directory. Since the single quotes prevents any sort of expansion, substitution and simple considers whatever to be present as a simple parameter in itself.
Just so that you remember in case you had typed the following
$ echo `$HOME`
(with the backquotes) you would get an error stating that the command not found. Since in this case the $HOME would be substituted with the path to your home directory (suppose /home/david) and the shell would try to execute the path as such. It would search for a program named (such as) /home/david. Remember that backquotes cause it to consider the part within the quotes to be considered as separate command and the output of that command would be substituted here. Hence in this case there is no command / program named as /home/david. Thus you would get an error when bash tries to execute that command
On the other hand when you type
$ echo "$HOME" or $ echo $HOME
You would get the expected output. i.e the path to your home directory would be printed at the output.
Thus you are now familiar with forming various filenames using wildcards. You would generally end up using the special characters such as quotes when trying to make complex shell commands. With this knowledge I hope you can get the shell to do some real good stuff for you.