Home > Archive > AWK > June 2004 > Need help with an array: only one row of array being used in for (i in array)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Need help with an array: only one row of array being used in for (i in array)
|
|
| Roland 2004-06-27, 8:55 pm |
| Hi,
I started looking at awk two days ago intrigued by the eaze of
handling data files. I wanted to compare preparing the file for
extraction with AWK to doing it in SAP BW using ABAP/4, a
fourth-generation programming language (what ever that means).
I have an input file that I want to process with an awk program:
# This program creates a CSV output file from a fixed width input file
# OFS sets the output field seperator of the output file
# FIELDWIDTH sets the fixed fieldwidths of the input file
BEGIN {
OFS = ";"; FIELDWIDTHS = "1 1 4 2 10 2 3 4 6 6 7 9 1 8 8 1 1
30 10 20 10 24 12 1 1 1 1 1 6 6 1 5
9 1 1 1 7 9 9 9 3 9 9 3 3 9 10 1 1 20 1 1 2 3 5 1 5
1 1 1 4 4 1 8 4 8 8 10 2 8 6 6 7";
convert_number["belopp"] = 12
convert_number["timmar"] = 9
}
# This code looks for characters in hours field ($9) and sum ($12) and
replaces them with numbers and
# -
# If a character is found and replaced, the first character in the
field (0)
# is to be replaced with a "-". p = -_____0, q = -____1 osv
# Ideally, a variable should be used to test $9 and $12
{
for ( i in convert_number )
var_field = convert_number[i]
if ($var_field ~ /p/) sub(/0/,"-",$var_field);
sub(/p/,0,$var_field);
if ($var_field ~ /q/) sub(/0/,"-",$var_field);
sub(/q/,1,$var_field);
if ($var_field ~ /r/) sub(/0/,"-",$var_field);
sub(/r/,2,$var_field);
if ($var_field ~ /s/) sub(/0/,"-",$var_field);
sub(/s/,3,$var_field);
if ($var_field ~ /t/) sub(/0/,"-",$var_field);
sub(/t/,4,$var_field);
if ($var_field ~ /u/) sub(/0/,"-",$var_field);
sub(/u/,5,$var_field);
if ($var_field ~ /v/) sub(/0/,"-",$var_field);
sub(/v/,6,$var_field);
if ($var_field ~ /w/) sub(/0/,"-",$var_field);
sub(/w/,7,$var_field);
if ($var_field ~ /x/) sub(/0/,"-",$var_field);
sub(/x/,8,$var_field);
if ($var_field ~ /y/) sub(/0/,"-",$var_field);
sub(/y/,9,$var_field);
}
# This code creates a new file with the field we want
{
print convert_number[i], var_field, $3, $5, $7, $9, $12, $22,
$38, $41, $66, $69 > "/Users/rolanddokas/Desktop/test.txt"
}
this is a sample of the output:
9;9;1150;6405075554;812;000000;01111360p
;730631
;000004000;T01;20040229;11
9;9;1150;6405075554;751;-00001;000291200;730631
;000004000;T01;20040229;11
9;9;1150;6405075554;752;-00004;000279100;730631
;000004000;T01;20040229;11
9;9;1150;6405075554;759;-00007;000017500;730631
;000004000;T01;20040229;11
The for (i in convert_number) just evalulates the field $9 and ignores
$12. The value in $12 on the first row 01111360p should be -11113600.
I don't get it. If I change the order of the elements in the array
then $12 is processed, and $9 is ignored.
Any help would be apreciated.
Roland
| |
| Patrick TJ McPhee 2004-06-28, 3:55 am |
| In article <c23585ac.0406271358.7a9535c9@posting.google.com>,
Roland <lupin3@bredband.net> wrote:
[...]
% for ( i in convert_number )
% var_field = convert_number[i]
This assigns each of the values held in convert_number to var_field,
in turn. The order in which the array indices are returned is not
specified -- in general, it depends on the hash algorithm used to
store the keys and the order in which the keys are set.
% if ($var_field ~ /p/) sub(/0/,"-",$var_field);
% sub(/p/,0,$var_field);
And this is evaluated using whatever the last of those fields happened
to be. You need to put all these if statements into the for loop.
On a related note, in the if statement quoted above, the first sub()
is executed under the control of the if statement, but the second
is not, and it will always be executed. I think you want something
like this:
for (i in convert_number) {
var_field = convert_number[i]
if ($var_field ~ /p/) {
sub(/0/,"-",$var_field);
sub(/p/,0,$var_field);
}
and so on. You could also have something like this in your BEGIN block
rv["p"] = 0; rv["q"] = 1; # and so on
and replace all the tests you're doing with
for (v in rv)
if ($var_field ~ v) {
sub(/0/,"-",$var_field);
sub(v,rv[v],$var_field);
}
--
Patrick TJ McPhee
East York Canada
ptjm@interlog.com
| |
| Roland 2004-06-28, 8:55 pm |
| Works great! Thanks for the help.
|
|
|
|
|