1757565 Members
2919 Online
108862 Solutions
New Discussion юеВ

ksh questions

 
SOLVED
Go to solution
Stuart Abramson_2
Honored Contributor

ksh questions

Hpux-admins:

I have two "variable strings" in a ksh script:

OLD_MPS="/u1001 /u1101 /u1102 /u1201 . . . /uXYYY"
NEW_MPS="/u2001 /u2101 /u2102 /u2201 . . . /uZQQQ"

I want to go through a mounted directory, and, respectively, for every occurrence of:
/u1001 replace it with /u2001
/u1101 replace it with /u2101

I don't want to replace "/u1" with "/u2". I actually want to replace the 1st occurrence in the "OLD_" list with the 1st occurrence in the "NEW_" list, the 2nd with the 2nd, the 3rd with the 3rd, etc.

My problem is not the outside loop, but the inside:

for OMP in $OLD_MPS
do
echo $OMP
# match with $NMP in $NEW_MPS

Can I turn my original variable strings into arrays? Then I could match
OLD_MPS[0] with NEW_MPS[0], etc. How would I do that?

Stuart
8 REPLIES 8
curt larson_1
Honored Contributor
Solution

Re: ksh questions

set [+/-]A name args
-A will cause name to be unset prior to the assignment

set -A oldMps $OLD_MPS
is how to do it
curt larson_1
Honored Contributor

Re: ksh questions

hopefully this won't be an issue,
but i believe that your limited to 1K array elements, i.e subscipts 0-1023
Wouter Jagers
Honored Contributor

Re: ksh questions

My 'top of the head' way to do this would be the following. A little counter should solve your problem. It might not be optimal, but hey, we're just renaming directories right ?

(note that I took the slashes out of OLD_MPS and NEW_MPS)

----------
OLD_MPS="u1001 u1101 u1102 u1201"
NEW_MPS="u2001 u2101 u2102 u2201"
TARGETDIR="."
count=1

for OMP in $OLD_MPS
do
NMP=`echo $NEW_MPS | cut -d " " -f$count`
find $TARGETDIR -type d -name $OMP -exec mv {} $NMP \; 2>/dev/null
echo $OMP to $NMP: done.
count=`expr $count + 1`
done
----------

hope it helps
regards
Wouter
an engineer's aim in a discussion is not to persuade, but to clarify.
john korterman
Honored Contributor

Re: ksh questions

Hi Stuart,
this is a simple example of reading $1 into an array:

#!/usr/bin/sh
typeset -i POS=0 i=1
while [ $POS -lt ${#1} ]
do
POS=$POS+1
KARAK=`echo ${1} | cut -c $POS`
STRENG[$POS]="$KARAK"
done

while [ $i -le $POS ]
do
echo "${STRENG[$i]}"
let i="$i+1"
done


but you of course need to take care of the "correct" number of spaces in order to e to make a sensible comparison; and use plenty of qoutes, e.g.:
# ./make_array.sh "/u1001 /u1101 /u1102 /u1201"

regards,
John K.

it would be nice if you always got a second chance
curt larson_1
Honored Contributor

Re: ksh questions

Done put quotes around the array values, as in:
set -A oldMps "$OLD_MPS"

you'll only get one array element

if you more the 1K values, you could try something like this

x=1
for OMP in $OLD_MPS
do
echo $OMP
echo $NEW_MPS | awk '{print $'$x';}'
x=$(( $x + 1 ))
done

but i think awk is limited to about 3K fields
Elmar P. Kolkman
Honored Contributor

Re: ksh questions

Using a counter can also be used otherwise...

idx=1
fld1=$(echo $OLD_MPS | cut -f$idx)
while [ -n $fld1 ]
do
if [ -d $fld1 ]
then
fld2=$(echo $NEW_MPS | cut -f$idx)
mv $fld1 $fld2
fi
idx=$(expr $idx + 1)
fld1=$(echo $OLD_MPS | cut -f$idx)
done

And there is another way too, by using not OLD_MPS as the loops input, but the content of your directory... But that is too much work to do out of head.
Every problem has at least one solution. Only some solutions are harder to find.
curt larson_1
Honored Contributor

Re: ksh questions

another way

#put each field on a seperate line
#create a coprocess
print "$NEW_MPS | tr "[:space:]" "\012*" |&

print "$OLD_MPS | tr "[:space:]" "\012*" |
while read old
do
read -p new
print "$old $new"
done
Stuart Abramson_2
Honored Contributor

Re: ksh questions

Thanks Curt:

Use "set -A" to turn 2 lists of corresponding values into two correspoinding arrays:

OLD_MPS=/u1001 /u1101 /u1102 /u1201
NEW_MPS=/u2001 /u2101 /u2102 /u2201

set -A OLD_ARRAY $OLD_MPS
set -A NEW_ARRAY $NEW_MPS
CNT=${#OLD_ARRAY[@]}
#
(( I=0 ))
while (( I < CNT ))
do
echo ${OLD_ARRAY[$I]} ${NEW_ARRAY[$I]}
(( I=I+1 ))
done