Search code examples
regexbashsed

regex replace all dots exept last one doesn't work


I try to rename a bunch of filenames so that the periods (exept the last one) got replaced with a hypen using sed.

I tried it this way (see below), but it doesn't work... Whats wrong with the script?

echo "test.test.test.txt" | sed -e "s/\.(?=.*\.)/-/g"

results in:

test.test.test.txt

instead of the desired:

test-test-test.txt


Solution

  • Using any sed you could change all .s to -s then the last - back to a .:

    $ echo "test.test.test.txt" | sed 's/\./-/g; s/-\([^-]*\)$/.\1/'
    test-test-test.txt
    

    With GNU awk or other that supports the non-POSIX extension of a 3rd arg to match() and gensub() you could do:

    $ echo "test.test.test.txt" | awk 'match($0,/(.*)(\..*)/,a){ print gensub(/\./,"-","g",a[1]) a[2] }'
    test-test-test.txt