Testing with Regular Expressions
Problem
Sometimes even the extended pattern matching of the extglob
option isn’t enough. What you really
need are regular expressions. Let’s say that you rip a CD of classical
music into a directory, ls that directory, and see
these names:
$ ls Ludwig Van Beethoven - 01 - Allegro.ogg Ludwig Van Beethoven - 02 - Adagio un poco mosso.ogg Ludwig Van Beethoven - 03 - Rondo - Allegro.ogg Ludwig Van Beethoven - 04 - "Coriolan" Overture, Op. 62.ogg Ludwig Van Beethoven - 05 - "Leonore" Overture, No. 2 Op. 72.ogg $
You’d like to write a script to rename these files to something simple, such as just the track number. How can you do that?
Solution
Use the regular expression matching of the =~ operator. Once it
has matched the string, the various parts of the pattern are available
in the shell variable $BASH_REMATCH
.
Here is the part of the script that deals with the pattern match:
#!/usr/bin/env bash # cookbook filename: trackmatch # for CDTRACK in * do if [[ "$CDTRACK" =~ "([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$" ]] then echo Track ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]} mv "$CDTRACK" "Track${BASH_REMATCH[2]}" fi done
Warning
Caution: this requires bash version 3.0 or newer because older versions don’t have the =~ operator. In addition, bash version 3.2 unified the handling of the pattern in the == and =~ conditional command operators but introduced a subtle quoting bug that was corrected in 3.2 patch #3. If the solution above fails, you may be using bash ...
Get bash Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.