File Name Substitution

   

Korn Shell: Unix and Linux Programming Manual, Third Edition, The
By Anatole Olczak

Table of Contents
Chapter 2.  Korn Shell Basics


File name substitution is a feature which allows strings to be substituted for patterns and special characters. This provides greater flexibility and saves a lot of typing time. Most frequently this feature is used to match file names in the current directory, but can also be used to match arguments in case and [[...]] commands.

The syntax for file name substitution is not the same as regular expression syntax used in some Unix commands like ed, grep, and sed. The examples in the following sections assume that the following files exist in the current directory:

 $ ls  a  .      .molog  abc     dabkup3  mobkup1  ..     a       dabkup1 dabkup4  mobkup2  .dalog ab      dabkup2 dabkup5 

The * Character

The * character matches any zero or more characters. This is probably the most frequently used pattern matching character. If used alone, * substitutes the names of all the files in the current directory, except those that begin with the "." character. These must be explicitly matched. Now, instead of typing in each individual file name to the cat command:

 $ cat dabkup1 dabkup2 dabkup3 dabkup4 ...  . . . 

You can do this:

 $ cat *  . . . 

The * character can also be used with other characters to match only certain file names. Let's say we only wanted to list the monthly backup files. We could do it like this:

 $ ls m*  mobkup1            mobkup2 

The m* matches any file name in the current directory that begins with m, which here would be mobkup1 and mobkup2. This command lists file names that end in 2:

 $ ls *2  dabkup2            mobkup2 

This command lists file names that contain ab. Notice that ab and abc are also listed:

 $ ls *ab*  ab       dabkup1   dabkup3          dabkup5  abc      dabkup2   dabkup4 

Remember that file name substitution only works with files in the current directory. To match file names in subdirectories, the / character must be explicitly matched. This pattern would match file names ending in .Z from any directories one-level under the current directory:

 $ ls */*.Z  bin/smail.Z        bin/calc.Z       bin/testsh.Z 

To search the next level of directories, another /* would need to be added.

 $ ls */*/*.Z  bin/fdir/foo.Z 

Be careful, because on some systems, matching files names in extremely large directories and subdirectories will generate an argument list error.

Don't forget that the "." character must be explicitly matched. Here, the . files in the current directory are listed:

 $ echo .*  . .. .dalog .malog 

The ? Character

The ? character matches exactly one character. It is useful when the file name matching criteria is the length of the file name. For example, to list two-character file names in the current directory, ?? could be used.

 $ echo ??  ab 

What if you wanted to list the file names in the current directory that had at least three or more characters in the name. The ??? pattern would match file names that had exactly three characters, but not more. You could try this:

 $ echo ??? ???? ????? . . . 

but that is not correct either. As you probably already guessed, the pattern to use would be ???*, which matches files names with three characters, followed by any zero or more characters. Let's try it:

 $ echo ???*  abc dabkup1 dabkup2 dabkup3 dabkup4 dabkup5  mobkup1 mobkup2 

If you only wanted to list the dabkup*, you could you the following pattern:

 $ echo dabkup?  dabkup1 dabkup2 dabkup3 dabkup4 dabkup5 

The [] Characters

The [] characters match a single, multiple, or range of characters. It is useful for when you want to match certain characters in a specific character position in the file name. For example, if you wanted to list the file names in the current directory that began with a or m, you could do it like this:

 $ ls a* m*  a        ab       abc      mobkup1  mobkup2 

or do it more easily using []:

 $ ls [am]*  a        ab       abc      mobkup1  mobkup2 

This command lists file names beginning with d or m, and ending with any number 1 through 5:

 $ echo [dm]*[12345]  dabkup1      dabkup3      dabkup5            mobkup2  dabkup2      dabkup4      mobkup1 

You could do the same thing using a range argument instead of listing out each number:

 $ echo [dm]*[1-5]  dabkup1      dabkup3      dabkup5            mobkup2  dabkup2      dabkup4      mobkup1 

In the range argument, the first character must be alphabetically less than the last character. This means that [c a] is an invalid range. This also means that pattern [0 z] matches any alphabetic or alphanumeric character, [A z] matches any alphabetic character (upper and lower case), [0 Z] matches any alphanumeric or upper case alphabetic character, and [0?] matches any alphanumeric character.

Multiple ranges can also be given. The pattern [a jlmr3?] would match files names beginning with the letters a through j, l, m, r, and 3 through 7.

The ! Character

The ! character can be used with [] to reverse the match. In other words, [!a] matches any character, except a. This is another very useful pattern matching character, since frequently you want to match everything except something. For example, if the current directory contained these files:

 $ ls  a        abc        dabkup2        dabkup4       mobkup1  ab       dabkup1    dabkup3        dabkup5  mobkup2 

and we wanted to list all of the file names, except those that started with d, we could do this:

 $ ls [0-ce-z]*  a        abc      mobkup2  ab       mobkup1 

or it could be done more easily using [!d]:

 $ ls [!d]*  a        abc      mobkup2  ab       mobkup1 

Multiple and range arguments can also be negated. The pattern [!lro]* would match strings not beginning with l, r, or o, *[!2?] would match strings not ending with 2 through 5, and *.[!Z] would match strings not ending in .Z.

Table 2.5. Basic Pattern-Matching Characters

?

match any single character

*

match zero or more characters, including null

[abc]

match any character or characters between the brackets

[x?/span>z]

match any character or characters in the range x to z

[a?/span>ce?/span>g]

match any character or characters in the range a to c, e to g

[!abc]

match any character or characters not between the brackets

[!x ?/span>z]

match any character or characters not in the range x to z

.

strings starting with . must be explicitly matched

Matching . Files

Certain characters like "." (period) must be explicitly matched. This command matches the file names .a,.b, and .c:

 $ ls .[a-c]  .a  .b  .c 

To remove all the files in the current directory that contain a ".", except those that end in .c or .h:

 $ rm *.[!ch] 

Complex Patterns

The latest version of the Korn shell also provides other matching capabilities. Instead of matching only characters, entire patterns can be given. For demonstration purposes, let's assume that we have a command called match that finds words in the on-line dictionary, /usr/dict/words. It's like the grep command, except that Korn shell patterns are used, instead of regular expression syntax that grep recognizes. The source code for match is listed in Appendix D.

*(pattern)

This format matches any zero or more occurrences of pattern. You could find words that contained any number of consecutive A's:

 $ match *(A)  A  AAA  AAAAAAAA 

Multiple patterns can also be given, but they must be separated with a | character. Let's try it with match:

 $ match *(A|i)  A  AAA  AAAAAA  i  ii  iii  iiiiii 

This pattern matches anti, antic, antigen, and antique:

 $ match anti*(c|gen|que)  anti  antic  antigen  antique 

This format is also good for matching numbers. The [1?]*([0?]) pattern matches any number 1?999999* (any number except 0).

?(pattern)

This format matches any zero or one occurrences of pattern. Here we look for one, two, and three letter words beginning with s:

 $ match s?(?|??)  s  sa  sac  sad  ... 

Here are some more patterns using this format:

 1?([0-9]) 

matches

 1, 10, 11, 12, ..., 19 
 the?(y|m|[rs]e) 

matches

 the, they, them, there, these 
+(pattern)

This format matches one or more occurrences of pattern. To find any words beginning with m followed by any number of iss patterns:

 $ match m+(iss)*  miss  mississippi 

Here is another pattern using this format. It matches any number.

 +([0-9]) 

matches

 0-9999999* 
@(pattern)

This format matches exactly one occurrence of pattern. Let's look for words beginning with Ala or Cla:

 $ match @([AC]la)*  Alabama  Alameda  Alamo  Alaska  Claire  Clara  Clare  ... 

Now for another number-matching pattern. This one matches any number 0?:

 @([0-9] 

matches

 0, 1, 2, 3, ..., 9 

Table 2.6. Other File Name Patterns

?(pattern-list)

match zero or one occurrence of any pattern

*(pattern-list)

match zero or more occurrences of any pattern

+(pattern-list)

match one or more occurrence of any pattern

@(pattern-list)

match exactly one occurrence of any pattern

!(pattern-list)

match anything except any pattern

pattern-list

multiple patterns must be separated with a | character

!(pattern)

This format matches anything except pattern. To match any string that does not end in .c, .Z, or .o:

 !(*.c|*.Z|*.o) 

or any string that does not contain digits:

 !(*[0-9]*) 
More Complex Patterns

The complex file patterns can be used together or even nested to generate even more sophisticated patterns. Here are a few examples:

 @([1-9])+([0-9]) 

matches

 1-9999999* 
 @([2468]|+([1-9])+([02468])) 

matches any even numbers

 2, 4, 6, 8, ... 
 @([13579]|+([0-9])+([13579])) 

matches any odd numbers

 1, 3, 5, 7, ... 

Disabling File Name Substitution

File name substitution can be disabled by setting the noglob option using the set command:

 $ set  o noglob 

or

 $ set  f 

The o noglob and f options for the set command are the same. Once file name substitution is disabled, pattern-matching characters like *, ?, and ] lose their special meaning:

 $ ls a*  a* not found  $ ls b?  b? not found 

Now we can create some files that contain special characters in their names.

 $ touch *a b?b c c d[]d  $ ls  *a    b?b    c c    d[]d 

Within [...] patterns, a \ character is used to remove the meaning of the special pattern-matching characters. This means that the [\*\?]* pattern would match file names beginning with * or ?.


       
    Top
     



    Korn Shell. Unix and Linux Programming Manual, Third Edition
    Korn Shell. Unix and Linux Programming Manual, Third Edition
    ISBN: N/A
    EAN: N/A
    Year: 2000
    Pages: 177

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net