Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Why does this skip lines?? 2

Status
Not open for further replies.

SMerrill

Programmer
Jan 19, 2002
145
US
I hope this is concise enough. I stripped out a lot of flack. This is probably a common telecomm problem.

PROBLEM: The following script processes the first field of a line and skips the rest of the fields in the line.
If I replace the red line of code with a print statement, it acts correctly. So something in my function(s) is eating the rest of the input line. But I'm an AWK beginner. Please help.

Code:
# UnBlkUDN.AWK
# Designed to "unblock" all the blocked DN's in the source file, 
# which is a list of unused DN's from a Nortel switch.
#
# A "DN" (dialed number) is a number that is 5 digits long.
# the DN must begin with a 3,4,5,6 or 8 to be unblocked.
#
# A "block" is defined as a number that is 2 to 4-digits long.
# If 42, then generate 12XXX where XXX is 000 - 999 inclusive.
# If 321, then generate 321XX where XX is  00 - 99  inclusive.
# If 5147, then generate 5147X where X is   0 - 9   inclusive.
# If 43456, then it is a DN, not a block; just print it out.
#
# The input consists of lines which contain up to 10
# mixed DN's or blocks delimited by several spaces.
#
# Only process lines which begin with a digit.
# All other lines in the input are garbage.

function Iterate(Field, max) {
#  printf("[%s]",Field)
  if(max==1){
    printf("%s ",Field)
  }
  else {
    for (i=0 ; i<=max ; i++)
    {
      if(max == 9){
        printf(&quot;%s%01d &quot;,Field,i)
      }
      else if(max == 99){
        printf(&quot;%s%02d &quot;,Field,i)
      }
      else if(max == 999){
        printf(&quot;%s%03d &quot;,Field,i)
      }
    }
  }
#  printf (&quot;[%s]\n&quot;,Field)
}

function Unblock(Field){
# the next line (printf) is a debug command
 printf(&quot;<%s>&quot;,Field)
 if (Field ~ /^[34568][0-9][0-9][0-9][0-9][0-9]$/) {
   Iterate(Field,  1)
 }
 else if (Field ~ /^[34568][0-9][0-9][0-9]$/)      {
   Iterate(Field,  9) 
 }
 else if (Field ~ /^[34568][0-9][0-9]$/)           {
   Iterate(Field, 99)
 }
 else if (Field ~ /^[34568][0-9]$/)                {
   Iterate(Field,999)
 }
# the next line (printf) is a debug command
 printf (&quot;</%s>\n&quot;,Field)
}

# If the line begins with a digit
/^[0-9]/ {

# Consider every field in the line separately
  for (i = 1; i <= NF; ++i) {

# If the field does not contain a star or a pound sign
    if ($i !~ /[*#]/) {

# unblock the field
Code:
Unblock($i);
Code:
    }
  }
}
The input file reads as follows. The green items are examples of those DNs which are completely skipped:
Code:
REQ:
AUD000
PRT
TYPE: LUDN
CUST 0
DN

CUSTOMER 00  - UNUSED DNS:
0001    0002    0005    0014    0022    0027    0031    0032    0043    0045
2111    2112    21130   21131   21132   21133   21134   21135   21136   21138
21139   2114    2115    2116    2117    2118    2119    212     213     214
215     216     217     218     219     22014   22015   22016   22017   22018
22019   2202    2203    2204    2205    2206    2207    2208    2209    221
222     223     224     225     226     227     228     229     24      3000
301
Code:
302     303     304     305     306     307     308     309     3100
Code:
3101
Code:
3102    3103    3104    3105    3106    3107    311     312     313
Code:
314
Code:
31507   3157    3158    3159    3160    3161    3162    3163    3165
Code:
3166
Code:
3167    3168    3169    317     318     3190    3191    3192    3193
Code:
3194
Code:
3198    3199    3206    3207    3208    3209    3210    3211    3212
Code:
81164   81505   81509   81510   81514   81519   81525   81527   81538   81552
81582   81583   81697   81752   81867   81881   82229   82426   82696   83036
85640   85698   85761   85764   85911   86590   86613   86782   87095   87109
87234   87473   87498   87563   87878   *0      *1      *2      *3      *4
*5      *6      *73     *74     *75     *76     *77     *78     *79     *8
*9      #0      #5      #6      #7      #8      #9

REQ: PRT
Thanks for your help,
--Shaun Merrill
 
I only used functions in awk 1 time.
is var i in Iterate local?
I think not.
not in linux.
you used it twice.

I hope this is the error.

regards Gregor Gregor.Weertman@mailcity.com
 
Hi Shaun,

It looks like since you do not use explicit &quot;return&quot; statements in your functions, the AWK language automatically returns the data that was processed by the function call. Therefore, you may simply need to add a &quot;print&quot; immediately after the call to the Unblock function that you indicated in &quot;red&quot; thusly:

Unblock($i);print

When the data is returned, it is returned back to the calling statement. Here, AWK will not automatically default to the print statement (meaning: print $0), so you must sometimes print explicitly.

Also, you may be making a recursive call to Unblock if that statement resides inside the function Unblock. I can't take more time today to examine your code today, but I am sure one of the other gurus in this forum can help you more.

I am hoping at least some of my comments will point you in the right direction on this problem.

Jesse

flogrr
flogr@yahoo.com

 
Flogr, Please note that the Unblock function ends just before the line
Code:
/^[0-9]/ {
Therefore, I am not being recursive.

Regarding your print statement, I do not wish to print there. This causes the output to contain 10 copies of the input line for every input line.

What I wish to know is exactly when does the code jump to the next input line?
--Shaun Merrill
 
Essentially, If I comment out the call to Unblock and replace it with a printf statment, like this, the program does not skip from <301> to <3101>. But as soon as I uncomment the call to Unblock, it skips <302> and <303> etc.
--Shaun Merrill

Code:
# If the line begins with a digit
/^[0-9]/ {

# Consider every field in the line separately
  for (i = 1; i <= NF; ++i) {

  Field=$i  
# If the field does not contain a star or a pound sign
    if (Field !~ /[*#]/) {

# unblock the field
    printf(&quot;<%s> &quot;,Field);
#       Unblock(Field);       
    }
  }
}
 
AHA. Gregor wins this match...

If I change the variable in the Iterate function to J instead of I, it works.

Therefore the variables are global, not local. The inner loop was 99'ing the I variable, so the outer loop thought it was done.

THANKS, GREGOR! [wavey]
 
to make a variable LOCAL and not to &quot;contaminate&quot; the globals you can use this convention:

function Iterate(Field, max, i)

The function will be called with TWO variable - a &quot;missing&quot; variable will be considered and made &quot;local&quot; in the body of the CALLED function. The AWK convention to distinguish PASSED variables from the LOCAL ones in the formal function declaration is to put all LOCAL variables at the END and separate them with EXTRA SPACES. vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top