0

I have been using a simple shell script placed in my user/.bin folder; Its job is very simple, copy specified files $1 and rename to $2; at least I had thought it to be that simple ...

The situation of use is this, I have a file nomenclature for my programming notes. The system is simple, an augmenting number followed by a letter, the rest of the file name contains only letters and underscores. Notes for a certain topic are called: 16115P-foobar.md whilst the code files for that topic are: 16115P-foobar.c 16115P-barfoo.h etc.

As the program progresses with each lesson, I am copying all program files before modifying them; So as to have files of each step of the course. As it is required of me to modify the program using the lessons topic; the first thing I do is copy and rename the files. The script is supposed to duplicate each file and rename them, changing only the sequential number, which is of my standard nomenclature:

e.g. 16115P-foobar.c is to be changed to 17121P-foobar.c ... etc.

The new number is specified by the user (my self only) by way of the second command line parameter; not automated by the script.

#!/bin/bash

for filename in $1*
do
    #
    # Copy and rename files
    #
    newname=`echo "$filename" | tr "$1" "$2"`
    echo $filename $newname
    cp $filename $newname
done

When I parse my file names like so:

:~/blah/blah/code$ copy_and_rename 16115P 17121P
16115P-file.c 27221P-file.c
16115P-input.c 27221P-input.c
16115P-main.c 27221P-main.c
16115P-output.c 27221P-output.c
16115P-recordshop.h 27221P-recordshop.h
16115P-utils.c 27221P-utils.c

I see now that tr is not the correct command to use here; I would appreciate some help.

Kind regards.

7
  • What are you expecting to happen? tr transliterates individual characters from a set: if you're trying to do string replacement it's not the right tool for the job – steeldriver Jan 6 '16 at 14:55
  • I am expecting the set to appear as entered in the second parameter; duplicate files with the number and letter code at the start of the name, quite simply replaced by $2. – iain Jan 6 '16 at 14:57
  • Ah ok, wrong tool! So sorry I miss read you first time round. Curious as it has been working, must be more out of luck and free memory space or something of the sort. Thank you for pointing that out; best I look for a string replacement command ... – iain Jan 6 '16 at 15:01
  • rename 's/old-name/new-name/' files Should do the trick, at least I think so. I wonder can I use shell parameters in there? – iain Jan 6 '16 at 15:06
  • You won't be able to use shell variables within single quotes, and using them within double quotes needs some care with regular expression tools (if the expanded variable contains characters that have special meaning in regex). What exactly are you trying to do? Please edit your post to make the desired new names explicit. – steeldriver Jan 6 '16 at 15:28
1

This is a task more suitable for regular expressions. Here I use regular expressions with awk ( since I am not familiar with rename command and perl regex, yes - shame on me ). Basic idea is that we take filename, get rid of all the numbers ( assuming you are pretty good at keeping up your own nomenclature and there will be no numbers after P- part).
Filenames are provided as command line arguments, can be typed one by one or used with wildcard as I've shown here. Then we read in the new number from user interactively, and stick that new number for each cropped filename.

$ ls
16115P-barfoo.h  16115P-foobar.c  16115P-foobar.md  updateNames.sh*
$ ./updateNames.sh 16115*                                                                                                        
Enter new number for all specified files: 
17121
17121P-barfoo.h
17121P-foobar.c
17121P-foobar.md
$ cat updateNames.sh                                                                                                             
#!/bin/bash

if [ $# -eq 0  ]; 
then
    echo "<<< Error: no arguments provided"
    exit 1
fi

echo "Enter new number for all specified files: " 
read NEWNUMBER
for file in "$@";
do
  BASE="$(echo "$file" | awk -F '-' '{ gsub( /[[:digit:]]/,""); print }')"
  echo $NEWNUMBER""$BASE
  # uncomment this line for actual copying
  # cp "$file" $NEWNUMBER""$BASE
done

$ 
1
  • Thank you Serg; that works perfectly. I have studied a little awk; it is nice to use and to become more familiar with it. – iain Jan 7 '16 at 15:15

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.