You want to rename a number of files. The filenames are almost right, but they have the wrong suffix.
Use a bash parameter expansion feature that will remove text that matches a pattern.
#!/usr/bin/env bash # cookbook filename: suffixer # # rename files that end in .bad to be .bash for FN in *.bad do mv "${FN}" "${FN%bad}bash" done
The for
loop will iterate over a list of filenames in the current
directory that all end in .bad
. The
variable $FN
will take the value of
each name one at a time. Inside the loop, the mv
command will
rename the file (move it from the old name to the new name). We need to
put quotes around each filename in case the filename contains embedded
spaces.
The crux of this operation is the reference to $FN
that
includes an automatic deletion of the trailing bad
characters. The ${ } delimit the reference so that the bash
adjacent to it is just appended right on
the end of the string.
Here it is broken down into a few more steps:
NOBAD="${FN%bad}" NEWNAME="${NOBAD}bash" mv "${FN}" "${NEWNAME}"
This way you can see the individual steps of stripping off the unwanted suffix, creating the new name, and then renaming the files. Putting it all on one line isn’t so bad though, once you get used to the special operators.
Since we are not just removing a substring from the variable but
are replacing the bad
with bash
, we could have used the substitution
operator for variable references, the slash (/). Similar to editor commands (e.g., those found
in vi and sed) that use the
slash to delimit substitutions, we could have written:
# Not anchored, don't do this mv "${FN}" "${FN/bad/bash}"
(Unlike the editor commands, you don’t use a final slash—the right-brace serves that function.)
However, one reason that we didn’t do it this way is because the substitution isn’t anchored, and will make the substitution anywhere in the variable. If, for example, we had a file named subaddon.bad then the substitution would leave us with subashdon.bad, which is not what we want. If we used a double slash for the first slash, it would substitute every occurrence within the variable. That would result in subashdon.bash, which isn’t what we want either.
# Anchored, so this is better, but TEST first mv "${FN}" "${FN/.bad/.bash}"
There are several operators that do various sorts of manipulation on the string values of variables when referenced. Table 5-1 summarizes them.
Table 5-1. String-manipulation operators
inside ${ … } | Action taken |
---|---|
| Substring starting character, length |
| Return the length of the string |
| Remove (shortest) front-anchored pattern |
| Remove (longest) front-anchored pattern |
| Remove (shortest) rear-anchored pattern |
| Remove (longest) rear-anchored pattern |
| Replace first occurrence |
| Replace all occurrences |
Try them all. They are very handy.
man rename
3.15.14.98