1

I'm trying to rename files using tr. The following command nearly works:

for file in ./*; do mv -v "$file" $(echo "$file" | tr ' []' '-' | tr -dc 'A-Za-z0-9_-' | tr '[:upper:]' '[:lower:]'); done

However, the command also strips dot characters. So, this file:

St Nicholas' church from NE [1235] 1936-08-01.jpg

becomes

st-nicholas-church-from-ne--1235--1936-08-01jpg

I've tried various ways to escape the dot, for instance using tr -dc 'A-Za-z0-9\._-' and tr -dc "A-Za-z0-9\._-"

The result invariably is that every character gets deleted. So my question, how to properly escape dot character in tr -dc?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
rkhff
  • 795

1 Answers1

1

Just add the dot in the "allowed characters" set. Also add the / character (part of the path).

for f in ./*; do
  new_f="$( printf "%s" "$f" | tr ' []' '-' | tr -dc 'A-Za-z0-9_./-' | tr '[:upper:]' '[:lower:]')"
  printf "Would move '%s' to '%s'\n" "$f" "$new_f"
done

This results in

Would move './St Nicholas' church from NE [1235] 1936-08-01.jpg' to './st-nicholas-church-from-ne--1235--1936-08-01.jpg'
Kusalananda
  • 333,661
  • Ah, yes - adding the '/' that did the trick! Never crossed my mind. Thanks a million. – rkhff Dec 30 '16 at 16:08
  • 1
    @rkhff Yes, I wasn't quite sure what you meant by "deleted". You either meant that the filename became empty, or that the files appeared to be deleted. In the second case, have a look to see if you now have a bunch of "hidden" files laying around (ls -a) whose filenames begin with a dot. – Kusalananda Dec 30 '16 at 16:16
  • Yep, lots of dot files in the directory - so the files appeared to have been deleted. – rkhff Dec 30 '16 at 16:40
  • @rkhff Just "appears" to have been deleted. They were renamed with the leading part of the path (./) changed to .. – Kusalananda Dec 30 '16 at 16:42