Adventures in Shell ScriptingToday I needed to do something different. I needed to copy all the files with the same DOS filename, to a new DOS filename, preserving the DOS file extensions. That is, I wanted to do
cp oldname.doc newname.doc cp oldname.txt newname.txt cp oldname.ods newname.ods ... for all the different extensions of "oldname"...and I don't know in advance what those extensions are. Essentially, what I wanted to do was cp oldname.* newname.* except that that command will not work, in DOS or Linux.* But I was sure that this could be done in Linux, with a shell script. (Feel free to skip the rest if this subject is not interesting to you.) * Update: A visitor, Dan, writes in to tell me that that command will work in the Windows shell, and also works in MS-DOS 6.22. I wasn't sure about Windows; but DOS was my mistake. It took perhaps an hour or so of digging through my shell scripting book, and searching with Google, before I found the clue in this forum thread. That didn't give me exactly what I needed, but it pointed me close enough to the final solution. #!/bin/bash
When invoked with "copyext oldname newname", $1 will be replaced with oldname and $2 will be replaced with newname. The for...do...done construct will repeat a single command multiple times. In this case, it repeats for each i in $1.* -- this means that i will successively take on each file name of the form "oldname.*" (recall that $1 will be replaced with oldname when the command is run). The first argument of the cp (copy) command is $i, which is just a file name that matches "oldname.*" -- for example, $i could be "oldname.txt". The second argument uses a built-in substitution function (this is what took me all the research). The phrase ${i#$1} means take the string given by variable i (e.g. "oldname.txt"), and remove from the front of it the string given by $1 (i.e., "oldname"). So that phrase just returns the extension of the matching filename (".txt"). Then that is combined with $2 ("newname") to give the new filename and the matching extension. I tested this by using echo instead of cp for i in $1.*
which just prints "oldname.ext newname.ext" for each file extension. I've added a few refinements -- such as checking that the correct number of arguments are present -- and added this to my toolbox. And now I have precisely the function I need! |