I have a shell script ren.sh

/usr/bin/mv /home/imp/imp/msgs/$1.PK1 /home/imp/imp/msgs/$1.BRD
/usr/bin/mv /home/imp/imp/msgs/$1.PK2 /home/imp/imp/msgs/$1.MIX

It works fine, but it only moves 2 files at a time (*.PK2 and *.PK1). I'd like for it to move all existing *.PK1 and *.PK2 files to *.MIXand *.BRD files

Is this possible?



for name in /home/imp/imp/msgs/*.PK1; do
    mv "$name" "${name%.PK1}.BRD"

for name in /home/imp/imp/msgs/*.PK2; do
    mv "$name" "${name%.PK2}.MIX"

The first loop will iterate over all *.PK1 files under /home/imp/imp/msgs and replace the filename suffix with .BRD.

The second loop does the analogous thing with the other set of files.

The variable expansion ${name%.PK2}.MIX will remove the string .PK2 from the end of the value stored in the variable name and then append the string .MIX to the end of the result of that.

| improve this answer | |
cat - <<\eof | make -f - SRCDIR="/home/imp/imp/msgs"
.PHONY:all force
all:$(wildcard $(SRCDIR)/*.PK[12]);
%.PK1:force;/usr/bin/mv "$@" "$(@:.PK1=.BRD)";
%.PK2:force;/usr/bin/mv "$@" "$(@:.PK2=.MIX)";

The cat command builds a makefile on the fly. The targets all and force are phony => target will always be rebuilt, in our case, mv is run each time. The $(wildcard ...) builds up a list of all the required *.PK1, *.PK2 files.

| improve this answer | |
set -- "BRD" "MIX"
for src in /home/imp/imp/msgs/*.PK[12]; do
   eval "dest=\${src%.*}.\${${src#${src%?}}}"
   /usr/bin/mv "$src" "$dest"

The underlying idea is we store the mapping of src filename extension into the new extension by means of "$@" array.

$src contains name.PK1 ${src%.*} contains name ${src#${src%?}} contains 1 thus dest is evaluated to "name" "." "BRD" = "name.BRD"

| improve this answer | |

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