annedroiid annedroiid - 5 months ago 13
Bash Question

Replace a string that includes a . using sed

I am trying to make a copy of all .txt files in a folder but renamed so that they are .html files.

for f in my-txt-folder/*.txt
do
a="$(echo $f | sed s/.txt/.html/)"
cp "$f" "$a"
done


This is my code so far, however when I run it I get the error

my.html-folder/file.txt: No such file or directory.


I know I'm getting this error because it renames the "-txt" in the enclosing folder, but how do I stop it doing that? I also tried having it replace "\.txt" but it still thinks the enclosing folder name is a match. How do I get it to only match ".txt" ? And before anyone asks, no I cannot just drill down into the folder and then run a script from there.

Answer

Match on end of line, e.g.

for f in my-txt-folder/*.txt
do
    a="$(echo $f | sed -e 's/\.txt$/.html/')"
    cp "$f" "$a"
done

Previously the "." you have matched with sed was a wildcard character, and you didn't anchor the pattern at end-of-line.

There is another solution all in bash from heemayl which was just posted; the advantage of an all-shell solution is that you don't have to learn the fine points of sed just yet.