For those who wish to apply a Basic Regular Expression to all file and directory names using nothing but Bash, GNU find, GNU sed, and GNU tr, consider using this snippet:
bash -c '
export LANG LC_ALL
find ./ -depth -name '"'"'.*.wma'"'"' -print0 | while read -d "" FILE ; do
echo -n "$OLD" \
| tr '\n' '\0' \
| sed -e '"'"'s/^\.\+//'"'"' \
| tr '\0' '\n' \
read -d "" NEW
if [ "$NEW" != "$OLD" -a -n "$NEW" -a -n "$OLD" ]; then
env LANG="$OLD_LANG" LC_ALL="$OLD_LC_ALL" \
mv -vi "$DIR/$OLD" "$DIR/$NEW" || exit $?
The first red part specifies the directories where the search is to be started in. They must all end with a slash.
The second red pattern is the glob pattern defining the file names to be modified.
The third red pattern is the regular expression or expressions to apply to the file name. Since it is a POSIX BRE (Basic Regular Expression, see Wikipedia
) and not a Perl Regular Expression, parentheses and the plus ("one or more") need to be escaped, and so is a bit different to when using rename
. Since this one operates on the file name, there will never be a slash in the subject.
may look a bit weird, but it just evaluates to one single-quote ('
). This is because the entire body of the command is in single quotes. (The body will only work in Bash, so I made sure it is run with Bash too.)
) and tr
are needed to stop sed
from applying the pattern in the middle of the file name, if it happens to have newlines in it. Newlines are temporarily converted to NULs (\0
), so if your pattern specifies newlines, use \0
instead of \n
The snippet is only lightly tested, but it really should work with any file and directory names possible in Linux.