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

Mega Bang
  • 49
  • 1
  • 9

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
  • 320,670
  • 36
  • 633
  • 936
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
  • 133,243
  • 15
  • 236
  • 397
Konflex
  • 126
  • 3
  • isn't there any better solution? just assigning value to `$i` variable – Mega Bang Jan 14 '22 at 11:31
  • I edit my answer, try this out – Konflex Jan 14 '22 at 11:39
  • still shows.. i'm on parrot os – Mega Bang Jan 14 '22 at 11:41
  • I reedited my answer, hope this one will suit you – Konflex Jan 14 '22 at 14:41
  • i came up with a solution similar to yours. I want to keep my code optimized. So i will use @they 's one – Mega Bang Jan 14 '22 at 15:07
  • 2
    the trick is called command substitution, and for [various reasons](https://unix.stackexchange.com/questions/5778/whats-the-difference-between-stuff-and-stuff), [it's better](https://unix.stackexchange.com/q/126927/170373) to use the `$()` syntax than backticks. Also you need to quote the arg to `echo` to avoid [various issues](https://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters/131767#131767) with the shell's word splitting and filename globbing. – ilkkachu Jan 14 '22 at 16:49