1

I have a shell script ren.sh

#!/bin/bash
/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?

MikeD
  • 810
ignatius
  • 401

3 Answers3

5

Yes.

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

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

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.

Kusalananda
  • 333,661
0
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)";
eof

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.

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

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"