Path-Name Expansion
Before Qshell interprets a command or passes arguments to a utility, it examines the command string for special characters called wildcards and replaces expressions with lists of file names . This process is formally known as path-name expansion but is commonly called globbing . Globbing gives you an easy way to work with groups of files while writing only a little bit of code.
It is important to understand that globbing is something Qshell does, not something that Qshell commands do. Qshell commands, whether scripts or utilities, just see the results of globbing. (Contrast this behavior to that of MS-DOS, which requires that the individual commands process wildcards for themselves .)
Globbing
Qshell could not glob were it not for metacharacters, also known as wildcards. Metacharacters are characters that represent other characters. For example, the letter a and the digit 5 are not metacharacters. They cannot represent other characters. The question mark, however, is a metacharacter because it can match any character. The globbing metacharacters are listed in Table 14.1.
Character |
Description |
---|---|
* |
Matches zero or more characters |
? |
Matches exactly one character |
[ ] |
Matches ranges or groups of characters |
! |
Negates a group or range of characters |
Escapes (disables) the metacharacter that follows it |
The following example shows the use of the asterisk metacharacter:
print * arglist.qsh bin bu.qsh casemon.qsh caseqtr.qsh casewild.qsh data.ascii data.ebcdic donde.qsh echoprocess.qsh edity.txt ftpmodel.txt goodoleboys.txt helpme mydata.csv myfile.txt myscript.qsh protos.jar protos.savf qsh_trace read002.qsh select01.qsh temp.txt test1.txt test1a.txt theirscript.qsh tscript.qsh upper.txt
Before executing the print utility, Qshell replaces the asterisk with a list of the files in the current directory.
An example of the question-mark metacharacter is shown here:
ls -dF ??? x.2* x.y bin/
The ls command displays the names of files with three-character names. The d option prevents the display of the contents of subdirectories. The F option appends a slash (/) to the end of directory names, an asterisk (*) to the end of executable file names, and an at sign (@) to the end of the names of symbolic links.
Globbing is case-sensitive. The following command uses the asterisk to copy all files whose names begin with a lowercase c to directory temp1:
Using Metacharacters with a Script
You can get a better feel for globbing by writing a shell script that prints the positional parameters. Such a script is listed in Figure 14.1, where it is named listargs.qsh.
# script name: listargs.qsh # declare -i argnbr=0 print "Number of arguments: $#" while [ "" ] do let argnbr=argnbr+1 printf "%3d (%s) " $argnbr "" shift done
Figure 14.1: The listargs.qsh script shows the effects of globbing.
The following example shows how the listargs.qsh script works without any globbing. Notice that Qshell has preserved the blanks in quoted strings.
listargs.qsh Qshell rulz "Qshell rulz" 'Qshell rulz' "Qshell rulz" Number of arguments: 5 1 (Qshell) 2 (rulz) 3 (Qshell rulz) 4 (Qshell rulz) 5 (Qshell rulz)
Running listargs.qsh with various globbing expressions shows you what Qshell does to the metacharacters before passing control to a script. In the first use of globbing with listargs.qsh, Qshell expands the *.txt expression into a list of all files that end with a period followed by txt:
listargs.qsh *.txt Number of arguments: 8 1 (edity.txt) 2 (ftpmodel.txt) 3 (goodoleboys.txt) 4 (myfile.txt) 5 (temp.txt) 6 (test1.txt) 7 (test1a.txt) 8 (upper.txt)
Since there are eight .txt files in the current directory, the listargs.qsh script runs as if the user had entered the eight file names as arguments.
The next example expands the globbing expression into a list of all file names that have an e as the second character:
listargs.qsh ?e* Number of arguments: 7 1 (helpme) 2 (read002.qsh) 3 (select01.qsh) 4 (temp.txt) 5 (temp1) 6 (test1.txt) 7 (test1a.txt)
In a slightly more complex example, you can use globbing to expand the expression into a list of files whose names begin with either an h or an r :
listargs.qsh [hr]* Number of arguments: 2 1 (helpme) 2 (read002.qsh)
The following globbing expression illustrates a range of file names:
listargs.qsh [d-g]* Number of arguments: 7 1 (data.ascii) 2 (data.ebcdic) 3 (donde.qsh) 4 (echoprocess.qsh) 5 (edity.txt) 6 (ftpmodel.txt) 7 (goodoleboys.txt)
All files whose names begin with any letter from d to g are listed. Globbing can also have the opposite effect, for example, listing files whose names do not begin with a letter in the range d to t :
listargs.qsh [!d-t]* Number of arguments: 11 1 (arglist.qsh) 2 (bin) 3 (bu.qsh) 4 (casemon.qsh) 5 (caseqtr.qsh) 6 (casewild.qsh) 7 (upper.txt) 8 (while001.qsh) 9 (x.2) 10 (x.y) 11 (yourscript.qsh)
Finally, here is a fairly complex use of metacharacters:
listargs.qsh [d-t][eiy][i-m]* Number of arguments: 6 1 (demo.csh) 2 (helpme) 3 (select01.qsh) 4 (tema) 5 (temp.txt) 6 (temp1)
Qshell includes filenames that begin with any letter between d and t , followed by an e , i , or y , followed by any letter from i to m , followed by zero or more characters.
Unmatched Expansion Expressions
If no filenames match the expansion pattern, Qshell passes the unmodified expression to the utility or script, as shown here:
echo x*x* x*x* /home/jsmith $ echo e*e* echoprocess.qsh
There are no files in the current directory whose names begin with an x and have another x in the file name, so the first echo displays the argument as it was keyed. However, the second echo is expanded because there is one file whose name begins with an e and has an embedded e .
Globbing and Case insensitive File Systems
In some case-insensitive file systems, letters used in patterns must be in uppercase. This is especially applicable to the qsys.lib (library) file system. (Although the qsys.lib file system is case insensitive, it stores object names in uppercase.) When using globbing for the library file system, be sure to use uppercase letters in the pattern, as shown in Figure 14.2. The first time listargs.qsh runs, the expression in parameter 1 is passed unmodified to the script. However, the second time listargs.qsh runs, the expression is globbed into four file names.
listargs.qsh /qsys.lib/smith.lib/*.pgm Number of arguments: 1 1 (/qsys.lib/smith.lib/*.pgm) /home/jsmith $ listargs.qsh /qsys.lib/smith.lib/*.PGM Number of arguments: 4 1 (/qsys.lib/smith.lib/EDITX.PGM) 2 (/qsys.lib/smith.lib/MON001.PGM) 3 (/qsys.lib/smith.lib/MONEVAL4.PGM) 4 (/qsys.lib/smith.lib/MONEVAL5.PGM)
Figure 14.2: When globbing is used with the library system, wildcard expressions must be in uppercase letters.
Preventing Globbing
You may tell Qshell not to expand path names . One simple way is to precede a metacharacter with a backslash character, like this:
echo * donde.qsh one one.qsh ten two upper.txt /home/jsmith/bin $ echo * *
Qshell expands the asterisk in the first echo command to a list of files in the current directory. However, the backslash in the second echo command prevents globbing, which makes the second echo print the asterisk literally.
In the following example, the first echo command displays the names of files that begin with the letter t , while the second command prints the string t* :
echo t* tema temp.txt temp1 test1.txt test1a.txt theirscript.qsh tscript.qsh /home/jsmith $ echo t* t*
Notice that the second echo does not print the backslash, since the backslash serves as an escape character.
A second way to prevent globbing is to place single quotes or double quotes around metacharacters, like this:
echo ?e*m* demo.csh helpme tema /home/jsmith $ echo '?e*m*' ?e*m* /home/jsmith $ echo "?e*m*" ?e*m*
You can also disable Qshell's automatic globbing feature. To do so, use the set command with the noglob option, as shown here:
# to disable globbing set -o noglob set -F # to enable globbing set +o noglob set +F
Notice that set has two forms. In the short form, shown in Figure 14.3, you use a lowercase f . In the longer form, you use a lowercase o followed by noglob , as shown in Figure 14.4.
echo ?e*m* demo.csh helpme tema temp.txt temp1 /home/jsmith $ set -f /home/jsmith $ echo ?e*m* ?e*m* /home/jsmith $ set +f /home/jsmith $ echo ?e*m* demo.csh helpme tema temp.txt temp1
Figure 14.3: This example illustrates the shorter form of the set command for disabling and enabling globbing.
echo d* data.ascii data.ebcdic demo.csh donde.qsh /home/jsmith $ set -o noglob /home/jsmith $ echo d* d* /home/jsmith $ set +o noglob /home/jsmith $ echo d* data.ascii data.ebcdic demo.csh donde.qsh
Figure 14.4: This example illustrates the longer form of the set command for disabling and enabling globbing.
When Globbing Fails
Depending on the utility, globbing might fail if the expansion produces more than 255 arguments. In that case, you might be able to achieve your objective by using the xargs utility to process a portion of the expanded arguments at a time. The xargs utility, which was discussed in chapter 12, reads data from standard input and passes it along to a command as arguments.
For example, the source physical file JSMITH/SRC in Figure 14.5 has 459 members . The print command is able to list the names of the members, but the ls command is not, due to a limitation in the number of parameters allowed for a program object. Recall that print is a built-in utility and not an external utility implemented by a program object. The xargs utility receives groups of 255 member names and sends them to the ls command.
print /qsys.lib/jsmith.lib/src.file/*.MBR /qsys.lib/jsmith.lib/src.file/ADDREC2R.MBR /qsys.lib/jsmith.lib/src.file/ADDREC D.MBR /qsys.lib/jsmith.lib/src.file/ADDRECPF.MBR/qsys.lib/jsmith.lib/src.file/A DRECR.MBR /qsys.lib/jsmith.lib/src.file/AFPM01.MBR /qsys.lib/jsmith.lib/src.fil ... (many lines omitted) ... .lib/src.file/YPGM01CL.MBR /qsys.lib/jsmith.lib/src.file/YPGM01RG#2.MBR /qsys.l ib/jsmith.lib/src.file/YPGM01RG.MBR /qsys.lib/jsmith.lib/src.file/YPGM02RG#2.MBR /qsys.lib/jsmith.lib/src.file/YPGM02RG.MBR /home/JSMITH $ ls -l /qsys.lib/jsmith.lib/src.file/*.MBR > dirlist.txt qsh: 001-0085 Too many arguments specified on command. /home/JSMITH $ print /qsys.lib/jsmith.lib/src.file/*.MBR xargs -n 255 ls -ld > dirlist.txt
Figure 14.5: You can sometimes use the xargs utility to get around the globbing restriction of 255 arguments in the expansion.
Summary
All users of Qshell should master globbing because it is inherent in all Qshell commands. Globbing, also called path - name expansion, occurs when Qshell substitutes file names for strings containing wildcard characters .