Rename file extension.

I have a list file that contains names of many files. I am reading one file name at a time using for loop
Then I like to create one more list file but with the file extension changed to "ctl".
Note: The file name can have any number of dots ".". But the extension after the last dot should be changed. And if there is no dot in file name it should append ".ctl"

for i in `cat listfile.txt`
do
    sed XXXX   >> New_listfile.txt
done

listfile contains data like this:

 abc.mnp.31235.txt
injo_kluo.miou.-mkop.pdf
12342_kjlu_3234.csv
integrate

I like the output in New_listfile like follows:

 
abc.mnp.31235.ctl
injo_kluo.miou.-mkop.ctl
12342_kjlu_3234.ctl
integrate.ctl

Help is really appreciated.

Use parameter substitution:

while read file
do
     echo "${file%.*}.ctl"
done < listfile.txt

Note: for i in `cat listfile.txt` is Dangerous Backticks

So use while loop instead as shown above.

This works could you please explain the below code

 echo "${file%.*}.ctl"

Not sure how this single line is doing great job.

From KSH manual

${parameter%pattern}
${parameter%%pattern}
	     If the shell pattern matches the end of the value of  parameter,
	      then  the  value of this expansion is the value of the parameter
	      with the matched part deleted; otherwise substitute the value of
	      parameter.   In  the first form the smallest matching pattern is
	      deleted and in the second form the largest matching  pattern  is
	      deleted.	When parameter is @, *, or an array variable with sub-
	      script @ or *, the substring operation is applied to  each  ele-
	      ment in turn.
1 Like
$ awk -F"." -v OFS="." ' { NF>1?$NF="ctl":$NF=$NF FS "ctl" } ; 1 ' file
abc.mnp.31235.ctl
injo_kluo.miou.-mkop.ctl
12342_kjlu_3234.ctl
integrate.ctl

Or

$ sed "s/\.[^.]*$//;s/$/.ctl/" file
abc.mnp.31235.ctl
injo_kluo.miou.-mkop.ctl
12342_kjlu_3234.ctl
integrate.ctl