I need to bulk rename files changing .-. to .

goal: file.-.txt is now file.txt

rename 's/.-./.' *.txt

Doesn't work. What's wrong?

  • No messages or output from the command: rename 's/.-././' *.txt
    – Alan
    Commented Oct 1, 2022 at 0:32
  • also, both .s in the search string needs to be escaped as \., otherwise they will match any character, not a literal .. perl rename uses regex matching. s/\.-\././g'
    – cas
    Commented Oct 1, 2022 at 4:40

3 Answers 3


You are not using the perl version of rename, because if you were you would have received the error Substitution replacement not terminated at (eval 1) line 1. due to the missing trailing / in the substitution expresssion.

Therefore, you need to use the syntax for the "other" rename

rename -vn -- '.-.' '.' *.txt

In this specific instance you don't really need to quote the source and destination patterns as they don't have shell glob characters (*, etc.), but it's good practice so I've done it here anyway.

Remove either or both -v (verbose) and -n (no action) when you're happy you've got something that works for your situation. Add the -a option to replace all the occurrences of .-. with ., for instance, to rename foo.-.bar.-.txt to foo.bar.txt instead of foo.bar.-.txt (beware it would still rename file.-.-.txt to file.-.txt) or -l to replace the last occurrence.

For the curious, the rename command took s/.-./. (yes, those literal seven characters) as the source pattern and the first matching filename from the *.txt glob as the destination pattern. It then tried to match the source pattern against each of the remaining files from the *.txt glob. Obviously this would have failed to match any, and because there was no syntactic error no message was output.


While I'll agree with @roaima is probably not one of the perl-based variants, with the perl-based variants, the syntax for that would be:

rename 's/\.(-\.)+/./g' ./*.txt

To replace all the occurrences of .-. with . in all the (non-hidden) file names that end in .txt. That would rename -a-b.-.-.c.-.-.txt with -a-b.c.txt for instance.

s/.-././g would rename it to -..-.c.-.txt as . is a regexp operator that matches any character and needs to be escaped so it matches a literal ..

s/\.-\././g would rename it to -a-b.-.c.-.txt.

And of course the important ./ prefix without which you introduce command injection vulnerabilities in some variants of rename.

For all kind of renaming, I prefer zsh's zmv as it doesn't have most of the problems and incompatibilities with all the rename variants and does some sanity checks before hand.

autoload -Uz zmv
zmv '*.txt' '${f//.(-.)##/.}'


zmv '(*).-(.txt)' '$1$2'

To only replace the -.- before txt with ..

  • Thanks! zmv did the trick!
    – Alan
    Commented Oct 2, 2022 at 2:59

What is wrong with rename 's/.-./.' *.txt

  1. Your s-command is not closed. Add a / at the back
  2. As roaima sais, dash '-' does not match underscore '_'
  • typo on my part the pattern is .-. not ._.
    – Alan
    Commented Oct 1, 2022 at 0:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .