1.0 Wildcards
Wildcard characters and
pipes and
redirections are the three magical powers of Linux commands, which can sublimate the power of text interface from shells to nuclear bombs, which is hard to compare with the graphical operation interface.
The main purpose of wildcards is to match file names. "Character" in wildcards is an English letter or number or symbol defined by ASCII code. For example, the English letter "A" "(ASCII=65) is a character. More than one character can form a string (String), for example, "XYZ" is a string.
Traditional file names are all encoded in ASCII code, so making good use of wildcards can simplify file operations, because the Linux shell itself can interpret wildcards, so almost any command related to files can be used with wildcards Characters, file names use wild characters to match called "globbing patterns" or "glob" for short, the common usage is as follows:
- "?": Matches any single character
Pay special attention to the emphasis on "single", that is to say, a "?" represents any single character that must exist. These characters can be letters or symbols or numbers, such as "?a" can match "3a" or "Ha" or "(a", etc.
example:
$ ls /dev/ram?? ← List "/dev/ram" followed by any two characters of files
/dev/ram10 /dev/ram11 /dev/ram12 /dev/ram13
/dev/ram14 /dev/ram15
$ cd /bin ← Enter the directory /bin
$ ls l? ← List the files whose first word is "l" (lowercase L) and the second word is any single character
ln ls
$ ls ?o?? ← List the 1st, 3rd, and 4th characters as any character, and the 2nd word is "o" files
more sort
$ ls ??? ← List the files with length=3
awk cat cut env pwd red rpm rvi sed tar
$ ls ?ed ← list the first word as any character, followed by "ed" file
red sed |
Wildcards can be used with almost any file-related command.
example:
$ mv l? /tmp
$ cp ch?.html /backup
$ rm ???.txt |
- "*": Matches zero or more characters of any length
Pay special attention to emphasizing that "none" is also counted, that is to say, a "*" means nothing to a string of any length. For example, "y*" can match "y" or "ya", "yes", "yahoo@tw" and so on.
example:
$ ls /dev/ram* ← List "/dev/ram" followed by a string of any length
/dev/ram /dev/ram10 /dev/ram13 /dev/ram2 /dev/ram5 /dev/ram8
/dev/ram0 /dev/ram11 /dev/ram14 /dev/ram3 /dev/ram6 /dev/ram9
/dev/ram1 /dev/ram12 /dev/ram15 /dev/ram4 /dev/ram7 /dev/ramdisk
$ cd /etc ← Enter the directory /etc
$ ls -d c*/ ←list the directories starting with "c" and followed by any name directory
cron.d/ cron.daily/ cron.hourly/ cron.monthly/ cron.weekly/ cups/
$ ls *.cfg ←List all files with the extension name "cfg" (the file name after "." is the extension name)
a2ps.cfg a2ps-site.cfg enscript.cfg
$ ls -d *-* ←List all files with "-" in the file name(the first or last character of the file name is "-" will also be established)
a2ps-site.cfg gnome-vfs-mime-magic jvm-commmon shadow-
bonobo-activation gpm-root.conf lsb-release.d system-release
dbus-1 group- passwd-
fedora-release gshadow- redhat-lsb
gnome-vfs-2.0 gtk-2.0 redhat-release
$ ls s*s ← list "s "All files beginning and ending with
services shells sudoers |
Although the wildcard "*" can match anything, it will exclude hidden files starting with the character "." Usage is summarized as follows:
| wildcards |
matching profile |
example |
| * |
Any file. Except hidden files at the beginning of "." |
ls * |
| *.* |
Any file name with ".", such as "readme.txt", "abc.", etc. but not including the file at the beginning of ".", such as ".Trash" |
cp *.* /tmp |
| .* |
Any hidden file |
rm .* |
| .*/ |
Any hidden directory ("/" is the directory at the end of the file name, and it will appear with ls -p or ls -F ) |
ls .*/ |
| */ |
Any directory, but does not include hidden directories starting with "." |
mv */ /tmp |
例:
$ ls -d .*/ ←List only hidden directories
$ ls -d .* ←List only hidden files
$ rm *. ←Delete only hidden files
$ rm -rf * ←Delete all files and directories in the working directory, But does not include hidden files
$ rm -r */ ← Delete all directories in the working directory, but does not include files and hidden directories |
Since "*" is insatiable in matching files, it is very convenient and dangerous to use. It is recommended to use wildcards to operate rm , mv and other commands before using ls to confirm the matching, so as not to accidentally delete files by mistake.
From these examples, you should be able to feel the flexibility of the text interface and the power of nuclear bombs. To give my own example, although I usually use Windows as my work platform, when backing up files, I obediently use the Windows "Command Prompt" (Command Prompt), that is, use the Windows text interface with wildcards To filter the files to be backed up, although the function of the text interface of Windows is not as good as one-tenth of that of Linux, it is also more convenient than using the mouse to select one by one in the graphical operation.
- "{PATTERN 1,PATTEN 2,..,PAATER n}" : Expands to multiple patterns
Enclosed in curly braces "{ }", within which are separated patterns by ",", and each pattern is expanded separately.
example:
$ echo iphone{3g,5,5c}, ← expand to list "3g", "5", and "5c"
iphone3g, iphone5, iphone5c,
$ echo iphone {3g,5,5c} , ← before and after "{ }" There is a difference in the output of characters with or without spaces. When there are spaces, the characters before and after the characters will not be expanded
iphone 3g 5 5c ,
$ ls -d {.*,.*/} ← only list hidden files and hidden directories
$ rm -fr {.*/,.*,*} ←Delete all files in the working directory, including hidden files and hidden directories (dangerous action)
$ cp -v /bin/{*ee*,*dd*} /tmp Copy files matching wildcard patterns "*ee*" and "*dd*"
`/bin/sleep' -> `/tmp/sleep'
`/bin/usleep' -> `/tmp/usleep'
`/bin/dd' -> `/tmp/dd' |
- "[ ]" : Specifies a character set to match against
characters in "[ ]" represent the character set to be matched. Its usage is similar to that of " ? ", but any character range of "?" Too wide, and this usage narrows its range, and the characters within the range are collected into "[ ]".
For example, "analy[zs]e" means that it can match "analyse" or "analyze". Another example "ID[abc]123" can match "IDa123" or "IDb123" or "IDc123" but not "IDabc123", because "[ ]" contains more than one character just match one of the matching characters.
example:
$ ls /dev/tty[14] ←list the files of tty1 or tty4 in the "/dev" directory
/dev/tty1 /dev/tty4
$ ls /dev/tty[123][45]
/dev/tty14 /dev/tty15 /dev/tty24 /dev/tty25 /dev/tty34 /dev/tty35
$ ls /dev/l[op]?
/dev/log /dev/lp0 /dev/lp1 /dev/lp2 /dev/lp3 |
^ back on top ^
- "[ - ]" : Specifies a range of characters to match
In many cases, if a character set is used to match a template "AD 199[012345]" that has a sequence such as wildcards, it can be expressed as "AD 199[0-5]" in a range.
The ranges are separated by "-", and there can be no space between characters and "-". But special attention must be paid to the matching range from small to large. If the system does not set locales, the order principle is based on the size of the ASCII code [Note]. However, the sorting of loocales may be different if there is a setting. Taking "en_US.UTF-8" encoding as an example, its sequence rule is "0<1<2 ...<9< a <A <b <B ... z<Z" (the later one is bigger).
If the matching screening range is not enough, you can always add it, such as [a-cA-C0-5]. Similar to the usage of character sets , no matter how much "[ ]" is written inside, it only represents one matching character. It is easier to understand clearly by looking at examples.
例:
$ LANG=en_US.UTF-8 ←Set the encoding of the locales to "en_US.UTF-8" (different locales results may be different)
$ ls /usr/bin/t[b-Y]e ←list "t" and "e", the middle is the file between "b to Y"
/usr/bin/tee /usr/bin/tie /usr/bin/toe
$ ls /usr/bin/t[Y-b]e ← invalid representation, because The matching filter range must be from small to large
ls: cannot access t[Y-b]e: No such file or directory
$ ls /usr/bin/icc[7-9i-t1-2]* ←the 4th character, range From "7~9" or "i~t" or "1~2" as long as one of them is established
/usr/bin/icc2ps /usr/bin/icclink /usr/bin/icctrans
|
For example, when installing Linux, the option to choose the language to install is "English", and the encoding is "en_US.UTF-8". If the user chooses a different language, it may affect the sorting of wildcards. Therefore, please enter LANG=en_US.UTF-8 to use this encoding before the experiment. Otherwise the results may be different from the above tests.
The effect of different encodings on the results is also the main shortcoming of wildcards, which can be overcome by using regular expressions .
- "[^ ]" or "[!]": Performs negation or inverse matching
"[^]" = "[!]", most of the shells can accept both, which is the specified character or character range for reverse match.
example:
$ ls /dev/tty[!14]
dev/tty0 /devtty3 /devtty6 /devtty8
dev/tty2 /devtty5 /devtty7 /devtty9
$ ls /usr/bin/t[!o-p]e
/usr/bin/tee /usr/bin/tie
$ ls /usr/bin/icc[^2]*
/usr/bin/icclink /usr/bin/icctrans |
- POSIX Character
The modern version of wildcards also supports the same POSIX character set as the regular expression . The POSIX character set can simplify the description, such as "[:digit:]" to represent all numbers , is equivalent to the wildcard template "[0123456789]" or "[0-9]".
Because the POSIX-character set is a subset of the square bracket notation "[ ]" introduced above (no matter how much "[ ]" is written in it, it only represents one of the matching characters), so the application needs to add square brackets Written as "[[:digit:]]".
Commonly used POSIX character sets are as follows:
| POSIX Character matches characters |
| POSIX |
ASCII |
Illustrate |
| [:alnum:] |
[A-Z,a-z,0-9] |
English letters and numbers |
| [:alpha:] |
[A-Z,a-z] |
Alphabet |
| [:blank:] |
|
Space(ASCII = 20H) and TAB(ASCII = 9H) |
| [:cntrl:] |
[0H-1FH,7FH] |
Control character |
| [:digit:] |
[0-9] |
Mumber |
| [:graph:] |
[21H-7EH] |
Characters that will be displayed |
| [:upper:] |
[A-Z] |
Uppercase letter |
| [:lower:] |
[a-z] |
Lower case letters |
| [:print:] |
[20H-7EH] |
Characters that will be displayed + spaces |
| [:punct:] |
[\]\[!"#$%&'()*+,./:;<=>?@\^_`{|}~-] |
Punctuation and symbols |
| [:space:] |
[ \t\r\n\v\f] |
Whitespace (characters not displayed) |
| [:xdigit:] |
[A-Fa-f0-9] |
Character in hexadecimal |
In addition to simplifying the description, using the POSIX character set has another advantage that the result is not affected by the locales. For a more detailed description of the POSIX character set, please refer to POSIX Characters in regular representation .
example:
$ ls -d /etc/[[:upper:]]* ← List files whose first character is uppercase
/etc/ConsoleKit /etc/DIR_COLORS.xterm /etc/Muttrc.local /etc/PolicyKit
/etc/DIR_COLORS /etc/Muttrc /etc/NetworkManager /etc/X11
|
The wildcard character is versatile and useful, but it can also confuse users at times, particularly when dealing with hidden files (files that start with a dot). For example, there may be many hidden files in the "/tmp" directory, but if I want to clear out all the files and directories in this directory, using
rm -fr * will not delete the hidden files. The main reason is that "*" represents anything, so
rm -fr * will delete not only the hidden files but also the current directory represented by "." and the parent directory represented by "..". However, this is not what we expect, so we have to leave the files starting with a dot untouched.
Of course, other commands like
ls * or
cp * ~/ will also encounter similar issues. One solution is to use ".[^.]" to match hidden files starting with a dot while excluding "." and "..". For example, rm
-fr .[^.]* indicates deleting all hidden files in the working directory.
In addition, it is not recommended to use very strange file names, such as the beginning of the file "-" or "#, @, %, \,?, |, {, }" and other strange characters in the file name, because it may cause let the wildcard fail (Many Linux distributions have this issue) or it is not easy to filter and match the desired files.Let's experiment!
Experiment
$ echo > abc ← Create a file with a length of three characters
$ ls ??? ← Verify
abc
$ echo > -12 ← Create a file "-12" (also three characters in length)
$ ls ??? ← Verify
ls: invalid option -- 2 ←??? Invalid
Try `ls --help' for more information.
$ ls *←List all files
ls: invalid option -- 2 Bizarre incident? wildcards completely fail.
$ rm -f ./-12 ←Kill this ghost file
$ ls ??? ←Verify
abc ←Normal |
1.1 rename - Renaming Multiple Files
In Linux, the
rename command is a powerful tool for renaming multiple files simultaneously. By using the appropriate wildcard characters and specifying the renaming rules, you can efficiently rename a large number of files in just a single command.
Its syntax is
rename OLD_NAME NEW_NANE PATTERN , where PATTERN is a pattern of wildcards, as long as it matches the pattern of wildcards, replace OLD_NAME with NEW_NANE.
It is easy to understand the usage with examples. For example, I took 50 photos in Keelung, but the default file name of the camera is IMAGE0001.jpg ~ IMAGE0050.jpg, but after a long time, I forgot that the photos were taken there, so I want to save
all The file name was changed to keelung0001.jpg ~ keelung0050.jpg of the shooting location. However, using the
mv command or using the Windows GUI to rename the files one by one is guaranteed to cause cramps, and it is much more convenient to use
rename .
Example: (Assume that there are 50 files in the working directory, including IMAGE0001.jpg~IMAGE0050.jpg)
$ rename IMAGE keelung IMAGE* ←Rename the file IMAGE0001.jpg ~ IMAGE0050.jpg to
keelung0001.jpg ~ keelung0050.jpg
|
Example: (Continued from the previous example, there are 50 files from IMAGE0001~IMAGE0050 in the working directory)
| $ rename IMAGE00 keelung00 IMAGE00[0-2]?.* ←Rename all files IMAGE0001.jpg ~IMAGE0029.jpg
to keelung0001.jpg~keelung0029.jpg, and keep the rest unchanged |
Example:
$ rename .config .cfg *.config ←Change the extension ".config" to ".cfg" in all working directories
$ rename - _ *-* ←Change the minus sign "-" in the file name of all files Change to underscore"_" |
Not just files,
rename can also be used to rename a large number of directories, which is actually very useful!
Example: (assuming that there are already directories catlog00~catlog99 in the home directory, a total of 100 directories)
$ rename ~/catlog ~/list ~/catlog?? ←in the home directory,Rename all directories from "catlog00"~"catlog99" rename to "list00"~"list99"
|
Of course, as long as you're happy, there's nothing wrong with using a sledgehammer to crack a nut.
rename can also be used to rename individual files.
例:
| $ rename abc wxyz * ← Rename "abc" to "wxyz" |
^ back on top ^