0

My bash script

echo -n "Round Name:"
read round
mkdir $round

echo -n "File Names:"
read $1 $2 $3 $4 $5 $6
cp ~/Documents/Library/Template.py $1.py $2.py $3.py $4.py $5.py $6.py .

I have automation for directories and want the same automation for filenames.

After taking unknown inputs, How can I make my shell scripts do this?
cp ~/Documents/Library/Template.py A.py B.py C.py D1.py D2.py $round/.

1
  • 1
    Question not clear: "it will do this … how do I do it?" — Do what? "Tried this" — did it work? Jan 5 at 12:13

2 Answers 2

0

Rather than reading the various strings interactively, just have the user pass them on the script's command line.

The following script would be called like

./script -d dirname -t templatefile -- string1 string2 string3 string4

... and it would create dirname if it doesn't already exist, and then copy templatefile into that directory with the root names given by the strings. If the template file has a filename suffix, this would be added to the end of each string to create the new filenames (after removing the suffix from the string as to not duplicate an already existing suffix).

You may bypass the step in the script that creates the directory by using the -n option, which makes the script assume that the directory specified by -d already exists.

#!/bin/sh

# Unset strings set via options.
unset -v dirpath do_mkdir templatepath

# Do command line parsing for -d and -t options.
while getopts d:nt: opt; do
    case $opt in
        d)
            dirpath=$OPTARG
            ;;
        n)
            do_mkdir=false
            ;;
        t)
            templatepath=$OPTARG
            ;;
        *)
            echo 'Error in command line parsing' >&2
            exit 1
    esac
done

shift "$((OPTIND - 1))"

# Sanity checks.
: "${dirpath:?Missing directory path (-d)}"
: "${templatepath:?Missing template file path (-t)}"

if [ ! -f "$templatepath" ]; then
    printf 'Can not find template file "%s"\n' "$templatepath" >&2
    exit 1
fi

if "${do_mkdir-true}"; then
    # Create destination directory.
    mkdir -p -- "$dirpath" || exit
fi
if [ ! -d "$dirpath" ]; then
    printf 'Directory "%s" does not exist\n' "$dirpath" >&2
    exit 1
fi

# Check to see whether the template file has a filename suffix.
# If so, save the suffix in $suffix.
suffix=${templatepath##*.}
if [ "$suffix" = "$templatepath" ]; then
    # No filename suffix.
    suffix=''
else
    # Has filename suffix.
    suffix=.$suffix
fi

# Do copying.
for string do
    # Remove the suffix from the string,
    # if the string ends with the suffix.
    string=${string%$suffix}
    cp -- "$templatepath" "$dirpath/$string$suffix"
done

To recreate your example at the end of your question, you would use this script like so:

./script -t ~/Documents/Library/Template.py -d "$round" -- A B C D1 D2
17
  • Does this mean i have to write cf -t ~/Documents/Library/Template.py -d "contest" -- A B C D1 D2 everytime if i have this script named cf in export PATH=$PATH:~/scripts/?
    – Mega Bang
    Jan 5 at 14:00
  • @MegaBang If that is the arguments that you want to run the script with, yes. You don't have to export the PATH variable though, as it's already exported. Using command line options and other arguments is usually easier than passing data to a script via read.
    – they
    Jan 5 at 15:04
  • Can you refactor this code to skip folder making and just create the files?
    – Mega Bang
    Jan 5 at 16:33
  • @MegaBang If the destination directory already exists, there will be no error. You still need to tell the script where the destination directory exists with -d though, or we wouldn't know where the files should be copied to.
    – they
    Jan 5 at 17:25
  • got it.. thank you
    – Mega Bang
    Jan 5 at 17:39
0
#!/bin/bash

echo -n "Round Name:"
read round
mkdir $round

read -r -p "Enter the filenames:" -a arr
for filenames in "${arr[@]}"; do 
cp ~/Documents/Library/Template.py $round/$filenames
done

This is done with an array, so it accepts infinite inputs. Just input the filenames separated by space, like so:

Enter the filenames:test1 test2 test3
4
  • I want to go to that directory. Could you please help me implement cd $round in this code?
    – Mega Bang
    Jan 5 at 11:46
  • You can add cd $round below mkdir $round without the && and remove the $round variable when doing cp in the loop
    – Alex
    Jan 5 at 11:48
  • 1
    @MegaBang Note that no script could change the directory for the session that invokes the script. Changing the directory for the script is in this case not necessary.
    – they
    Jan 5 at 11:51
  • @Alex As an alternative to your loop: tee "${arr[@]/#/$round/}" >/dev/null <~/Documents/Library/Template.py
    – they
    Jan 5 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.