I guess the subject asks it all, but I am wondering (before I go and code a COBOL module) if conversion of regular ASCII data to COMP-3 is possible on a UNIX environment (AIX 5.1)? Any help would be appreciated! Thanks, Dave
If you are talking about "Packing" the data which is what COMP-3 does in COBOL then yes you will have to write a COBOL program to do that. I don't know of anything in UNIX that will do that without using COBOL. Of course I am not a UNIX expert so I could be wrong. Good Luck!
jyoung, meet ksh. This script will convert an integer argument to packed decimal.
#! /usr/bin/ksh
typeset -R1 dig
typeset -i8 octal
typeset -Z4 result
#
# handle sign
number=$1
sign="C"
if ((number<0)) ; then
((number=-number))
sign="D"
fi
#
# prepend a zero if needed
((ilength=${#number}))
if ((ilength/2*2 == ilength)) ; then
number=0${number}
((ilength=${#number}))
fi
#
# conversion loop
((olength=ilength/2))
packswitch=1
char2=$sign
while ((ilength)) ; do
dig=$number
((ilength=ilength-1))
typeset -L$ilength newnumber=$number
number=$newnumber
if ((packswitch)) ; then
char1=$dig
octal=16#${char1}${char2}
result=${octal#??}
echo packing $olength $char1 $char2 $octal $result
output[olength]=$(print -n \\${result})
((olength=olength-1))
else
char2=$dig
fi
((packswitch=!packswitch))
done
#
# output the packed decimal to prove it worked
olength=${#output[*]}
o=0
while ((o <= olength)) ; do
print -n ${output[o]} | od -t x1
((o=o+1))
done
exit 0
Thanks Per. I'm assuming this doesn't work for decimal data? Only true integers?
/home/rse0/xxgvlqr> /home/rse0/xxgvlqr/ascii_to_packed.ksh 123.45
packing 3 5 C 8#134 0134
/home/rse0/xxgvlqr/ascii_to_packed.ksh[39]: 16#.4: bad number
With packed decimal, any decimal point is assumed. It is not stored in the data.
Per, thanks very very much for your help. I think this will save me from having to write a COBOL routine. One more question: do you know of a way to put out "low-values" or "high-values" through a script. Basically we want our summary record to look like this:
high values positions 1-5
# of records in the file positions 6-10
Totaling the records, I can handle. LOL. Just need to know if there is a way to "write" low values or hgih values within a shell script. Thanks.
So the total field is numeric rather than packed decimal? I think this should do it:
high5=$(print -n \\0377\\0377\\0377\\0377\\0377)
Define your total field like this:
typeset -Z5 total
to get the leading zeroes you will need.
Remember that ksh will add new line characters unless you supress them:
print -n ${high5}${total}
To test this:
$ cat x
#! /usr/bin/ksh
high5=$(print -n \\0377\\0377\\0377\\0377\\0377)
typeset -Z5 total
total=123
print -n ${high5}${total} | od -t x1
$ ./x
0000000 ff ff ff ff ff 30 30 31 32 33
0000012
$
Per, need some more help. Noting your quote above, we have a field that is signed (see below) that I need to put into comp-3 format. Any ideas? I know you said the decimal is implied, but what about handling a positive or negative number?
+000000000050408
or
-000086214050408
Take another look. The script handles negative numbers.
Oops, sorry about that. Was so concerned about the packing piece of the puzzle that I overlooked the negative handling. One thing in your script has me confused. I did a man on "od" and there is no "-t" option. What is this line doing:
print -n ${output[o]} | od -t x1
Also, in your script, is it the "$result" variable that is ultimately holding the packed output? With all of the outputting in different formats and display messages (and my "light" UNIX coding experience), I got a little disoriented.
Here is the AIX man page for od. I see the -t option which is required for posix compatability.
Look at the end of my script:
#
# output the packed decimal to prove it worked
olength=${#output[*]}
o=0
while ((o <= olength)) ; do
print -n ${output[o]} | od -t x1
((o=o+1))
done
The output is in "output".
I have tried using the sample script, but have a problem when trying to pack a number that has concurrent zeroes. The result of packing to two zeroes results in a null hex value, that cannot be printed. Is there any way to deal with this?
Thanks for the info.
I found this thread showing how to make a Comp-3 field. However, I have to accomplish the opposite:
Read a count variable stored as Comp-3 telling me how many records to expect. Then, report back if I received all of the records in an ftp.
So, any ideas or past scripts, on how to convert a signed Comp-3 field?
Thanks.
The main problem is that comp-3 is just binary data. Thoughout the thread I am doing stuff like "print -n ${output[o]} | od -t x1" because the data is binary. This is why coutulea's question made no sense. So where is your data? How do you propose to make it available to a shell script? If you can isolate the comp-3 field and pump it through od and read the out of od into a script, it probably can be done.