Chapter 17. file globbing

Table of Contents

* asterisk
? question mark
[] square brackets
a-z and 0-9 ranges
$LANG and square brackets
preventing file globbing
practice: shell globbing
solution: shell globbing

The shell is also responsible for file globbing (or dynamic filename generation). This chapter will explain file globbing.

* asterisk

The asterisk * is interpreted by the shell as a sign to generate filenames, matching the asterisk to any combination of characters (even none). When no path is given, the shell will use filenames in the current directory. See the man page of glob(7) for more information. (This is part of LPI topic 1.103.3.)

[paul@RHELv4u3 gen]$ ls
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File*
File4  File55  FileA  Fileab  FileAB
[paul@RHELv4u3 gen]$ ls file*
file1  file2  file3  fileab  fileabc
[paul@RHELv4u3 gen]$ ls *ile55
File55
[paul@RHELv4u3 gen]$ ls F*ile55
File55
[paul@RHELv4u3 gen]$ ls F*55
File55
[paul@RHELv4u3 gen]$

? question mark

Similar to the asterisk, the question mark ? is interpreted by the shell as a sign to generate filenames, matching the question mark with exactly one character.

[paul@RHELv4u3 gen]$ ls
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File?
File4  FileA
[paul@RHELv4u3 gen]$ ls Fil?4
File4
[paul@RHELv4u3 gen]$ ls Fil??
File4  FileA
[paul@RHELv4u3 gen]$ ls File??
File55  Fileab  FileAB
[paul@RHELv4u3 gen]$

[] square brackets

The square bracket [ is interpreted by the shell as a sign to generate filenames, matching any of the characters between [ and the first subsequent ]. The order in this list between the brackets is not important. Each pair of brackets is replaced by exactly one character.

[paul@RHELv4u3 gen]$ ls 
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls File[5A]
FileA
[paul@RHELv4u3 gen]$ ls File[A5]
FileA
[paul@RHELv4u3 gen]$ ls File[A5][5b]
File55
[paul@RHELv4u3 gen]$ ls File[a5][5b]
File55  Fileab
[paul@RHELv4u3 gen]$ ls File[a5][5b][abcdefghijklm]
ls: File[a5][5b][abcdefghijklm]: No such file or directory
[paul@RHELv4u3 gen]$ ls file[a5][5b][abcdefghijklm]
fileabc
[paul@RHELv4u3 gen]$

You can also exclude characters from a list between square brackets with the exclamation mark !. And you are allowed to make combinations of these wild cards.

[paul@RHELv4u3 gen]$ ls 
file1  file2  file3  File4  File55  FileA  fileab  Fileab  FileAB  fileabc
[paul@RHELv4u3 gen]$ ls file[a5][!Z]
fileab
[paul@RHELv4u3 gen]$ ls file[!5]*
file1  file2  file3  fileab  fileabc
[paul@RHELv4u3 gen]$ ls file[!5]?
fileab
[paul@RHELv4u3 gen]$

a-z and 0-9 ranges

The bash shell will also understand ranges of characters between brackets.

[paul@RHELv4u3 gen]$ ls
file1  file3  File55  fileab  FileAB   fileabc
file2  File4  FileA   Fileab  fileab2
[paul@RHELv4u3 gen]$ ls file[a-z]*
fileab  fileab2  fileabc
[paul@RHELv4u3 gen]$ ls file[0-9]
file1  file2  file3
[paul@RHELv4u3 gen]$ ls file[a-z][a-z][0-9]*
fileab2
[paul@RHELv4u3 gen]$

$LANG and square brackets

But, don't forget the influence of the LANG variable. Some languages include lower case letters in an upper case range (and vice versa).

paul@RHELv4u4:~/test$ ls [A-Z]ile?
file1  file2  file3  File4
paul@RHELv4u4:~/test$ ls [a-z]ile?
file1  file2  file3  File4
paul@RHELv4u4:~/test$ echo $LANG
en_US.UTF-8
paul@RHELv4u4:~/test$ LANG=C
paul@RHELv4u4:~/test$ echo $LANG
C
paul@RHELv4u4:~/test$ ls [a-z]ile?
file1  file2  file3
paul@RHELv4u4:~/test$ ls [A-Z]ile?
File4
paul@RHELv4u4:~/test$

If $LC_ALL is set, then this will also need to be reset to prevent file globbing.

preventing file globbing

The screenshot below should be no surprise. The echo * will echo a * when in an empty directory. And it will echo the names of all files when the directory is not empty.

paul@ubu1010:~$ mkdir test42
paul@ubu1010:~$ cd test42
paul@ubu1010:~/test42$ echo *
*
paul@ubu1010:~/test42$ touch file42 file33
paul@ubu1010:~/test42$ echo *
file33 file42

Globbing can be prevented using quotes or by escaping the special characters, as shown in this screenshot.

paul@ubu1010:~/test42$ echo *
file33 file42
paul@ubu1010:~/test42$ echo \*
*
paul@ubu1010:~/test42$ echo '*'
*
paul@ubu1010:~/test42$ echo "*"
*

practice: shell globbing

1. Create a test directory and enter it.

2. Create the following files :

file1
file10
file11
file2
File2
File3
file33
fileAB
filea
fileA
fileAAA
file(
file 2

(the last one has 6 characters including a space)

3. List (with ls) all files starting with file

4. List (with ls) all files starting with File

5. List (with ls) all files starting with file and ending in a number.

6. List (with ls) all files starting with file and ending with a letter

7. List (with ls) all files starting with File and having a digit as fifth character.

8. List (with ls) all files starting with File and having a digit as fifth character and nothing else.

9. List (with ls) all files starting with a letter and ending in a number.

10. List (with ls) all files that have exactly five characters.

11. List (with ls) all files that start with f or F and end with 3 or A.

12. List (with ls) all files that start with f have i or R as second character and end in a number.

13. List all files that do not start with the letter F.

14. Copy the value of $LANG to $MyLANG.

15. Show the influence of $LANG in listing A-Z or a-z ranges.

16. You receive information that one of your servers was cracked, the cracker probably replaced the ls command. You know that the echo command is safe to use. Can echo replace ls ? How can you list the files in the current directory with echo ?

17. Is there another command besides cd to change directories ?

solution: shell globbing

1. Create a test directory and enter it.

mkdir testdir; cd testdir

2. Create the following files :

file1
file10
file11
file2
File2
File3
file33
fileAB
filea
fileA
fileAAA
file(
file 2

(the last one has 6 characters including a space)

touch file1 file10 file11 file2 File2 File3
touch file33 fileAB filea fileA fileAAA
touch "file("
touch "file 2"

3. List (with ls) all files starting with file

ls file*

4. List (with ls) all files starting with File

ls File*

5. List (with ls) all files starting with file and ending in a number.

ls file*[0-9]

6. List (with ls) all files starting with file and ending with a letter

ls file*[a-z]

7. List (with ls) all files starting with File and having a digit as fifth character.

ls File[0-9]*

8. List (with ls) all files starting with File and having a digit as fifth character and nothing else.

ls File[0-9]

9. List (with ls) all files starting with a letter and ending in a number.

ls [a-z]*[0-9]

10. List (with ls) all files that have exactly five characters.

ls ?????

11. List (with ls) all files that start with f or F and end with 3 or A.

ls [fF]*[3A]

12. List (with ls) all files that start with f have i or R as second character and end in a number.

ls f[iR]*[0-9]

13. List all files that do not start with the letter F.

ls [!F]*

14. Copy the value of $LANG to $MyLANG.

MyLANG=$LANG

15. Show the influence of $LANG in listing A-Z or a-z ranges.

see example in book

16. You receive information that one of your servers was cracked, the cracker probably replaced the ls command. You know that the echo command is safe to use. Can echo replace ls ? How can you list the files in the current directory with echo ?

echo *

17. Is there another command besides cd to change directories ?

pushd popd