I have a great number of files whose name is "img800400_497708.307247.png", and I would like to change all dots (periods) to an underscore using the console. How can I do that?
2 Answers
You can do this fairly easily with the rename
command. The only problem is preserving the extension. We start by replacing all the dots, but then replace _png
with .png
. You'll obviously need to adapt that for other extension types.
cd /path/to/images
rename 's/\./_/g; s/_png$/.png/' *.png -vn
Note: the -vn
on the end will only demonstrate what it would do. It's a safety trigger. Check the command does what you want and then remove that last part.
A super-simple test harness:
$ touch file.{01..10}.png
$ rename 's/\./_/g; s/_png$/.png/' *.png -vn
file.01.png renamed as file_01.png
file.02.png renamed as file_02.png
file.03.png renamed as file_03.png
file.04.png renamed as file_04.png
file.05.png renamed as file_05.png
file.06.png renamed as file_06.png
file.07.png renamed as file_07.png
file.08.png renamed as file_08.png
file.09.png renamed as file_09.png
file.10.png renamed as file_10.png
-
-
Since the
rename
command is perl-based, how about using a negative lookahead to replace only those periods that are not followed by the extension? something likerename -vn -- 's/[.](?!png$)/_/g'
Commented Apr 27, 2015 at 14:36 -
Why not simply remove the trailing g in the first command to only replace the first dot. g means global and replace all occurrence of pattern. Also options do not go at the end but after the command name and -vn does not exist but -v -n does. I mean use
rename -v -n 's/\./_/' *.png
– solsTiCeCommented May 3, 2015 at 22:31
A bash solution that removes the extension, replaces the periods with underscores, then adds back the extension:
for f in *.png; do g="${f%.*}"; echo mv -- "$f" "${g//./_}.png"; done
Remove the echo
once you have satisfied yourself whether it works. It could fairly easily be extended to a general .ext
extension if you have more than one file type, for example
for f in *.*; do g="${f%.*}"; e="${f##*.}"; echo mv -- "$f" "${g//./_}.$e"; done
-
That's unnecessary complex. Just use one
/
if you only want to replace the first.
:for f in *.png; do; echo mv -- "$f" "${f/./_}"; done
. Commented Apr 27, 2015 at 22:30 -
@DavidOngaro I don't want to only replace the first
.
, I want to replace all except the last Commented Apr 27, 2015 at 22:36 -
Ok, but from @user3601754's example it seems he doesn't need that? But only he can tell what he actually needs... Commented Apr 27, 2015 at 23:45