1

My bash script

#!/bin/bash
read -r -p "Enter the filenames: " -a arr
for i in "${arr[@]}"
do
    echo $i | sed 's/\(.*\)\..*/\1/'
    cp -v ~/Desktop/library/template.py "$i".py
done

If i write A B.py C D.py, this script will turn it into A.py B.py C.py D.py
-v flag of cp -v explains what is being done

but i don't want to print the edited filenames echo $i. It's annoying.

How can i do that?
alternative solutions are also appreciated

2 Answers2

3

You want to trim the value of $i after the last dot in the string.

You can do this like so:

i=${i%.*}

This removes the shortest suffix string from $i that matches the filename globbing pattern .* (a dot followed by any string).

If you know you want to trim off .py specifically:

i=${i%.py}

This means you could write your cp command like so:

cp -v ~/Desktop/library/template.py "${i%.py}.py"

This would be the only command in the loop body and it would remove the .py filename suffix from $i, if the value had such a suffix, and then add .py. This ensures that the destination filename always has .py as the filename suffix and at the same time avoids doubling the suffix.


Suggestion for script:

#!/bin/sh

for string do cp -v ~/Desktop/library/template.py "${string%.py}.py" done

Or,

#!/bin/zsh

for string; cp -v ~/Desktop/library/template.py $string:r.py

... which uses the zsh shell, its alternative, shorter, form for the for loop, and its :r modifier to remove the filename extension before adding .py to the name.

You would call either script like so:

./script A B.py C D.py
Kusalananda
  • 333,661
1

I found an trick:

#!/bin/bash
read -r -p "Enter the filenames: " -a arr
for i in "${arr[@]}"
do
    var=$(echo "$i" | sed 's/\(.*\)\..*/\1/')
    cp -v ~/Desktop/library/template.py "$var".py
done
ilkkachu
  • 138,973
Konflex
  • 126