bash globbing filename expansion - ghdrako/doc_snipets GitHub Wiki
- https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
- http://tldp.org/LDP/abs/html/patterns.html
- https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
Globbing
File globbing supports multiple different matching mechanisms, similar to regular expressions:
- Matching specific characters from options written inside brackets, e.g.,
[ab]
(a or b) - Matching characters from a sequence written inside brackets, e.g.,
[0-9]
to match a number character or[a-d]
to match a, b, c, or d - Caret (
^
) character to negate the selection - Dollar sign (
$
) to denote the end of the name - Choosing between several patterns using
(PATTERN|PATTERN2)
Examples
Pattern | Explanation |
---|---|
backup-*.gzip |
Match all files starting with backup- that have .gzip file extension. |
[ab]* |
Match all files that start with either a or b. |
[^ab]* |
Match all files that don’t start with a or b. |
*.??? |
Match all files whose file extension has exactly three characters. |
`(*.??? | *.??)` |
The asterisk character (*) will by default not match any hidden files starting with a dot.
for file in *.jpg; do
convert "$file" "${file%.jpg}.png"
# Replaces '.jpg' extension with '.png'
done
Negation with !
rm !(*.zip) # Delete everything EXCEPT .zip files
find . -type f ! -name ".*" # # Find non-hidden files (those NOT starting with '.')
Use { } for generating several filenames.
mkdir project_{a,b,c} # Creates directories project_a, project_b, project_c
touch report_{01..05}.txt # Creates report_01.txt through report_05.txt
Case-Insensitive matching
By default, wildcard matches are case-sensitive. To get around this (use carefully!)
- shopt Command:
shopt -s nocasematch # Turns on case-insensitive matching
shopt -u nocasematch # Turns off case-insensitive matching
Matching across Directories (Caution!)
- Globstar (
**
) (Bash 4.0+) Enables recursive wildcard matching through subdirectories. Use carefully due to performance impact on large directories.
rm -rf **/temp_* # Delete all files/folders starting with "temp_" recursively
Replaces 'project_data' with 'final_data' in filenames using ${variable/text/replace}
# Renaming with Pattern Matching
for file in project_data_*.csv; do
mv "$file" "${file/project_data/final_data}"
done
Archive a Specific Date Range
mkdir daily_backups
tar -czf "daily_backups/backup_$(date +%Y-%m-%d).tar.gz" log_2023-11-??.txt
Check integrity of backup files
for backup in *.zip; do
if ! zip -T "$backup"; then # Check zip integrity with '-T'
echo "WARNING: Corrupted backup found: $backup"
fi
done