OS X renaming using parameter expansion
When it comes to rename files via
command line there is no rename utility under OS X without
installing Homebrew. But I still
never needed to install it since there is a lot you can do by
just making use of the shell parameter
expansion.
The parameter expansion allows you to manipulate variables in a very convenient way and when mixed with the mv command you have an unstoppable renaming tool. Let's see first what are variables and what is this parameter expansion:
$ var='PIC0001.JPG' $ echo ${var} PIC0001.JPG
In the example above you can see that we have assigned the value PIC0001.JPG to a variable named var and in the next line we have just printed its content. The same example with a little bit of magic:
$ echo ${var/PIC/2014_Holiday_} 2014_Holiday_0001.JPG
Here I substituted the ugly PIC preffix used by the photo camera and added the title of the album. We'll see the details on how this works later on.
Now if I wanted to rename all the pictures from the command line I would just iterate over all them:
for file in *.JPG; do echo mv "$file" "${file/PIC/2014_Holiday_}"; done
You can safely execute the previous command, no change will be made to this files because we added the echo to just show the command to be executed. Delete it to make changes effective.
Now that we have seen a simple example for remaning let's get deeper on what you can do with parameter expansion with some examples.
In order to do some safe testing I would recommend creating a new directory and inside put some random empty files:
for i in $(seq 1 100); do touch "$i-${RANDOM}-$i.txt"; done
That will create something like:
$ ls 1-21912-1.txt 2-16712-2.txt 3-22319-3.txt ...
Now that you have the dummy files test and understand the following examples:
Replacing patterns with strings
The format of this expansion is:
# Replace first match of the pattern only: ${variable/pattern/replace} # Replace all matches of the pattern: ${variable//pattern/replace}
And now a batch example, replace all dashes in files by underscores:
for file in *.*; do echo mv "$file" "${file//-/_}"; done mv 1-21912-1.txt 1_21912_1.txt mv 10-848-10.txt 10_848_10.txt mv 100-26921-100.txt 100_26921_100.txt ...
Important: Note that the double slash // will replace all matching appearances, but if you use just one slash then the replacement will stop after the first match. Try it.
Remove a pattern from the beginning
The format of this expansion is:
# Remove the pattern in the beginning: ${variable#pattern} # Remove the pattern in the beginning (longest match possible): ${variable##pattern}
In action, remove the first part of the file:
$ for file in *.*; do echo mv "$file" "${file#*-}"; done mv 1-21912-1.txt 21912-1.txt mv 10-848-10.txt 848-10.txt mv 100-26921-100.txt 26921-100.txt ...
See the difference when using ##:
$ for file in *.*; do echo mv "$file" "${file##*-}"; done mv 1-21912-1.txt 1.txt mv 10-848-10.txt 10.txt mv 100-26921-100.txt 100.txt
The double hash ## is matching with the longest possibility and taking the last - in the file.
Remove a pattern at the end
The format of this expansion is:
# Remove the pattern at the end: ${variable%pattern} # Remove the pattern at the end (longest match possible): ${variable%%pattern}
This works exactly like the previous expansion but matching the end. An example of removing the extension:
for file in *.*; do echo mv "$file" "${file%.txt}"; done mv 1-21912-1.txt 1-21912-1 mv 10-848-10.txt 10-848-10 mv 100-26921-100.txt 100-26921-100 ...
Replace only a substring
Just like any substring function in a variety of languages, the format is:
# Cut string from offset: ${variable%offset} # Cut string from offset until length: ${variable%offset:length}
Remove 3 first characters:
for file in *.*; do echo mv "$file" "${file:3}"; done mv 1-21912-1.txt 1912-1.txt mv 10-848-10.txt 848-10.txt mv 100-26921-100.txt -26921-100.txt
Take from the 3rd and then 5 characters:
for file in *.*; do echo mv "$file" "${file:3:5}"; done mv 1-21912-1.txt 1912- mv 10-848-10.txt 848-1 mv 100-26921-100.txt -2692
Want more?
http://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
Happy renaming!