Awk script returns nothing


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Awk script returns nothing
# 1  
Old 05-19-2012
Awk script returns nothing

Code:
HSLIST=$1

LFILE=$2

STRING=$3

awk 'BEGIN {
  while((getline < "'${HSLIST}'")>0)
     S[$0]

  FS="\n"; RS="}\n"
}

/servicestatus {/ && /service_description='${STRING}'/ {

  for(X in D) delete D[X];

  for(N=2; N<=NF; N++)
  {
       split($N, A, "=");
       D[A[1]] = A[2]
       i = 3;
       while (i in A) 
          D[A[1]] = D[A[1]] "=" A[i++];
  }

  if (D[" host_name"] in S)
       printf("%s -------- %s -------- %s -------- %s -------- %s -------- %s -------- %s -------- %s\n", D["host_name"], D["service_description"], D["check_execution_time"], D["check_latency"], D["last_check"], D["last_hard_state_change"], D["current_state"], D["plugin_output"])

}' $LFILE

Can someone please explain to me why the above code isn't pulling out anything from a file that contain several chunks like the one below?

when i run the above code, i get back nothing.

synopsis:

i have a file that contains several of the chunks below. the chunks belong to several servers. one server may have several chunks associated with it.

in the below example, this specific chunk belongs to a server called "sky-01.net". there may be other chunks like this in a file, with service description "CPU_CHECK", "DISK_CHECK", etc.


Code:
servicestatus {
        host_name=sky-01.net
        service_description=LOAD_CHECK
        modified_attributes=1
        check_command=check_load!68!90
        check_period=24x7
        notification_period=24x7
        check_interval=30.000000
        retry_interval=2.000000
        event_handler=
        has_been_checked=1
        should_be_scheduled=1
        check_execution_time=1.362
        check_latency=7.887
        check_type=0
        current_state=0
        last_hard_state=0
        last_event_id=2523376
        current_event_id=2611954
        current_problem_id=0
        last_problem_id=1127556
        current_attempt=1
        max_attempts=1
        state_type=1
        last_state_change=1337124526
        last_hard_state_change=1337124526
        last_time_ok=1337433055
        last_time_warning=0
        last_time_unknown=1335465427
        last_time_critical=1337123063
        plugin_output=INFORMATIONAL:  Check is ok. NOthing to worry about.
        long_plugin_output=
        performance_data=
        last_check=1337433055
        next_check=1337434855
        check_options=0
        current_notification_number=0
        current_notification_id=2699849
        last_notification=0
        next_notification=0
        no_more_notifications=0
        notifications_enabled=1
        active_checks_enabled=1
        passive_checks_enabled=1
        event_handler_enabled=1
        problem_has_been_acknowledged=0
        acknowledgement_type=0
        flap_detection_enabled=0
        failure_prediction_enabled=1
        process_performance_data=1
        obsess_over_service=1
        last_update=1337433118
        is_flapping=0
        percent_state_change=0.00
        scheduled_downtime_depth=0
        }

# 2  
Old 05-19-2012
It's hard to tell as you are missing to provide some clues to understand your code, its parameters and more information about its input file, however I would probably insert
Code:
gsub(/^[ \t]+/, "", $N);

just before
Code:
split($N, A, "=");

This User Gave Thanks to jlliagre For This Post:
# 3  
Old 05-19-2012
Quote:
Originally Posted by jlliagre
It's hard to tell as you are missing to provide some clues to understand your code, its parameters and more information about its input file, however I would probably insert
Code:
gsub(/^[ \t]+/, "", $N);

just before
Code:
split($N, A, "=");

And probably need to remove the whitespace in the string:
Code:
if (D[" host_name"] in S)

so that it is
Code:
if (D["host_name"] in S)

This User Gave Thanks to agama For This Post:
# 4  
Old 05-19-2012
jillagre and agama's suggestions both worked.

can someone please explain the code to me in its totality?

the script runs like this:

Code:
code.sh  /var/tmp/listofhosts.txt  /usr/chunk.cfg LOAD_CHECK

# 5  
Old 05-19-2012
Here is your code with some comments to describe what is going on:

Code:
awk 'BEGIN {
  while((getline < "'${HSLIST}'")>0)    # read all names from the host list
     S[$0]                              # create an instance in the S hash; ="" is implied

  # file should have been closed with close( filename )

  FS="\n"; RS="}\n"                     # after reading host list; change field and record separators
                                        # this effectively causes each block to be one input record
}

/servicestatus {/ && /service_description='${STRING}'/ {    # execute the following code when the input record
                                                            # contains "servicestatus (" and "service_description="
  for(X in D) delete D[X];                                  # delete previous values in D;  delete( D ) is more efficient

  for(N=2; N<=NF; N++)                                      # for each field, starting with 2, (these are name=value pairs)
  {
       split($N, A, "=");                                   # divide the field int array A.  a[1] contains name, a[2] contains the value
       D[A[1]] = A[2]                                       # create an instance in the D hash using the name to map to value
       i = 3;                                               # not in your example input, but this handles the case where the
       while (i in A)                                       # name=value is actually  name=value=more=stuff
          D[A[1]] = D[A[1]] "=" A[i++];                     # by adding more=stuff to the value saved in D[name]
  }

  if (D[" host_name"] in S)                                 # if the hostname sussed from the data was in the file read; print the info
       printf("%s -------- %s -------- %s -------- %s -------- %s -------- %s -------- %s -------- %s\n", D["host_name"], 
   D["service_description"], 
   D["check_execution_time"], 
   D["check_latency"], 
   D["last_check"], 
   D["last_hard_state_change"], 
   D["current_state"],
   D["plugin_output"])

}' $LFILE



There are a couple of things that should be changed: close the host list file after reading it; that is just good practice. The for loop to delete the values in D isn't needed. You can just delete( D ) or use split to delete the hash more efficiently. Lastly, I don't like the quoting games used to incorporate shell variables. It's messy, and leads to bugs during maintenance.

I also don't think it's necessary to play games with the record/field separators; at least not in this case. Just for fun, here's an example that brings in shell variables without quoting games, and doesn't need to play with the separators:

Code:
awk -v hostf=$HSLIST -v desc=$STRING '
    BEGIN {
        while( (getline < hostf) > 0 )
            hlist[$1];
        close( hostf );                         # good practice to close a file when done with it

        split( "host_name service_description check_execution_time check_latency last_check last_hard_state_change current_state plugin_output", desired, " " );
    }

    /servicestatus {/ { snarf = 1; next; }      # beginning of desired chunk -- start saving info

    /}/ && snarf {
        if( data["host_name"] in hlist )                    # if host was in the list; print its data
        {
            for( i = 1; i <= length( desired ); i++ )       # print desired output; less efficient, but more flexible when adding or changing order
                printf( "%s%s", i > 1 ? " ------- " : "", data[desired[i]] );
            printf( "\n" );
        }
        delete( data );                     # use split( "", data, "." );  if awk version does not support delete()
        snarf = 0;
        next;
    }

    snarf {                                 # saving data; cache value (all after first =) in data hash
        nm = $1;
        gsub( "=.*", "", nm );              # drop everything after first = from name string
        val = $0;
        sub( "^[^=]*=", "", val );          # drop name= from the value string
        data[nm] = val;                     # save it
    }
' input-file

This User Gave Thanks to agama For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Remove carriage returns from awk output

I'm on Linux version 2.6.32-696.3.1.el6.x86_64, using the Ksh shell. I'm working with the input file: John Daggett, 341 King Road, Plymouth MA Alice Ford, 22 East Broadway, Richmond VA Orville Thomas, 11345 Oak Bridge Road, Tulsa OK Terry Kalkas, 402 Lans Road, Beaver Falls PA Eric Adams,... (2 Replies)
Discussion started by: prooney
2 Replies

2. Shell Programming and Scripting

Python call to bash script returns empty string

Hi all, I need help figuring out why my script won't work when envoked from web interface. First off, I'm fairly new to Linux and Shell scripting so, my apologies for being ignorant! So I have a python script that I envoke through a web interface. This script envokes my shell script and... (8 Replies)
Discussion started by: arod291
8 Replies

3. Shell Programming and Scripting

Execution of shell script returns error 127

Hi All, While running shell script i got following output. interpreter "usr/bin/ksh" not found sh: step1.sh: not found. ldnhpux | oracle >echo $? 127 - Running command "which ksh" retruns "usr/bin/ksh". - I found some information on web stating to remove extra carriage return chars,... (8 Replies)
Discussion started by: RuchirP
8 Replies

4. Shell Programming and Scripting

awk print last line returns empty string

hello I have a file with lines of info separated with "|" I want to amend the second field of the last line, using AWK my problem is with geting awk to return the last line this is what I am using awk 'END{ print $0 }' myFile but I get an empty result I tried the... (13 Replies)
Discussion started by: TasosARISFC
13 Replies

5. Shell Programming and Scripting

for loop returns more output with awk

I need to get total number of hdisk not assigned to any VGs. PDC # lspv |grep None |awk '{print $1}' |wc 131 131 1099 So, it shows 131 hdisks. I need to look at the individual hdisk fget_config info like below: PDC # fget_config -Av |grep hdisk230 hdisk230 dac1 229... (4 Replies)
Discussion started by: Daniel Gate
4 Replies

6. Emergency UNIX and Linux Support

Adding carriage returns to file using sed/awk

Hello, I need help adding carriage returns at specific intervals (say 692 characters) to a text file that's one continous string. I'm working in AIX5.3. Any quick help is appreciated. Thanks! (2 Replies)
Discussion started by: bd_joy
2 Replies

7. Shell Programming and Scripting

awk returns null?

hi i try to check if awk returns null and i dont know how it's works this is the command set EndByC = `ls -l $base | awk '/.c$/ {print $9}'` if ($EndByC=="") then #check if ther is XXX.c directory echo Sorry ther is no XXX.c folder "in" $base path echo the XXX.c folder is necessary... (6 Replies)
Discussion started by: frenkelor
6 Replies

8. Shell Programming and Scripting

awk returns an integer?

I need to extract a value from a text file into a ksh script, and change the last two letters to "00". awk gets the right value (2500 in this example), but the variable has no value. I use the following command: StartTime=expr nawk 'NR==20 {print $11;exit}' $New_FILE echo 1 $StartTime... (4 Replies)
Discussion started by: Iliklev
4 Replies

9. Shell Programming and Scripting

FIND returns different results in script

When I execute this line at the command prompt I get a different answer than when I run it in a script? Any ideas on how to resolve? I'm trying to find all files/dir in a directory except files that start with the word file. Once I get this command to work, I will add the "delete" part to the... (6 Replies)
Discussion started by: blt123
6 Replies

10. UNIX for Dummies Questions & Answers

script returns prompt

Hi, I am trying to create a script that will loop through my oratab file and pull out the instance name. Here is script: for instance in $(cat /etc/oratab|egrep ':N|:Y'|grep -v \*|grep -v \#|cut -f1 -d':') do ... (3 Replies)
Discussion started by: kburrows
3 Replies
Login or Register to Ask a Question