Here's a concise cheatsheet on Expansion and Pattern Matching in Linux, complete with a markdown table of metacharacters and their matches. This can serve as a quick reference for understanding how to use these powerful features in the shell effectively.
Linux shells, like Bash, offer various ways to expand variables and match patterns using special characters called metacharacters. These are used in command-line operations, scripting, and file manipulation, making tasks more efficient and versatile.
Brace expansion is used to generate arbitrary strings by specifying a pattern within braces {}
.
-
Syntax:
echo file{1,2,3}.txt
-
Example:
touch file{A,B,C}.txt # Creates files: fileA.txt, fileB.txt, fileC.txt
Tilde expansion replaces the tilde ~
with the home directory path of the current user or specified user.
-
Syntax:
cd ~
-
Example:
cd ~/Documents # Changes directory to the Documents folder in the home directory
Parameter expansion is used to manipulate variables and retrieve their values in different ways.
-
Syntax:
${parameter} ${parameter:-word} # Use default value if unset
-
Example:
NAME="Linux" echo ${NAME} # Outputs: Linux echo ${UNSET_VAR:-Default} # Outputs: Default
Command substitution allows the output of a command to replace the command itself in the command line.
-
Syntax:
$(command) `command`
-
Example:
TODAY=$(date) echo "Today is $TODAY" # Outputs: Today is Fri Aug 02 14:21:30 UTC 2024
Arithmetic expansion allows you to perform arithmetic operations using the shell.
-
Syntax:
$((expression))
-
Example:
echo $((5 + 3)) # Outputs: 8
Pathname expansion uses wildcards to match filenames and paths.
-
Syntax:
ls *.txt
-
Example:
echo *.txt # Matches all files ending with .txt in the current directory
Linux shells use metacharacters to match patterns, providing flexibility in file manipulation and command execution. Here is a table of common metacharacters and their functions:
Metacharacter | Description | Example | Matches |
---|---|---|---|
* |
Matches zero or more characters | file* |
file , file1 , file123 , fileA |
? |
Matches exactly one character | file?.txt |
file1.txt , fileA.txt |
[...] |
Matches any one of the enclosed characters | file[abc].txt |
filea.txt , fileb.txt , filec.txt |
[^...] |
Matches any one character not enclosed | file[^abc].txt |
filex.txt , filey.txt |
[a-z] |
Matches any one character in the specified range | file[a-c].txt |
filea.txt , fileb.txt |
[!a-z] |
Matches any character not in the specified range | file[!a-c].txt |
filed.txt , filex.txt |
{} |
Matches any of the patterns separated by commas | file{1,2,3}.txt |
file1.txt , file2.txt |
{a..z} |
Matches characters in a specified range (brace expansion) | file{a..c}.txt |
filea.txt , fileb.txt , filec.txt |
\ |
Escapes special characters to treat them literally | file\*.txt |
file*.txt |
Here's a deeper look into pattern matching using the metacharacters from the table above:
-
Example:
ls *.jpg
-
Description:
- Matches all
.jpg
files, such asimage.jpg
,photo1.jpg
, andcat.jpg
.
- Matches all
-
Example:
ls file?.txt
-
Description:
- Matches
file1.txt
,file2.txt
, etc., but notfile123.txt
.
- Matches
-
Example:
ls file[123].txt
-
Description:
- Matches
file1.txt
,file2.txt
, orfile3.txt
.
- Matches
-
Example:
ls file[^123].txt
-
Description:
- Matches any file like
filex.txt
,filea.txt
, but notfile1.txt
,file2.txt
, orfile3.txt
.
- Matches any file like
-
Example:
touch {fileA,fileB,fileC}.txt
-
Description:
- Creates
fileA.txt
,fileB.txt
,fileC.txt
.
- Creates
-
Example:
echo {a..d}
-
Description:
- Outputs
a b c d
.
- Outputs
The shell also provides advanced pattern matching operators like #
, %
, ##
, and %%
, used primarily in parameter expansion:
-
Syntax:
${variable#pattern}
-
Example:
FILENAME="path/to/file.txt" echo ${FILENAME#*/} # Outputs: "to/file.txt" (removes shortest match from the beginning)
-
Syntax:
${variable##pattern}
-
Example:
FILENAME="path/to/file.txt" echo ${FILENAME##*/} # Outputs: "file.txt" (removes longest match from the beginning)
-
Syntax:
${variable%pattern}
-
Example:
FILENAME="path/to/file.txt" echo ${FILENAME%/*} # Outputs: "path/to" (removes shortest match from the end)
-
Syntax:
${variable%%pattern}
-
Example:
FILENAME="path/to/file.txt" echo ${FILENAME%%/*} # Outputs: "path" (removes longest match from the end)
FILENAME="document.txt"
BASENAME=${FILENAME%.txt}
echo $BASENAME
# Outputs: "document"
Here's a brief walkthrough of some practical examples to demonstrate how expansion and pattern matching can be applied:
You can use brace expansion to rename multiple files quickly.
mv file{1,2}.txt newfile{1,2}.txt
# Renames file1.txt to newfile1.txt and file2.txt to newfile2.txt
Use brace expansion to create multiple directories with a single command.
mkdir project/{src,bin,lib,doc}
# Creates directories: project/src, project/bin, project/lib, project/doc
Combining pathname expansion and commands like find
makes it easy to locate and remove files.
find . -name "*.log" -type f -delete
# Finds and deletes all .log files in the current directory and subdirectories
Using *
and ?
can help process a batch of files simultaneously.
cp backup_2024-??.tar.gz /backups
# Copies files like backup_2024-01.tar.gz, backup_202