1

I have a working command

awk  -F '[)#/(:]' 'BEGIN  { fw="";dev=""} {if ($0~/sh failover/) fw=$1 ; if (($0~/This host/)||($0~/Other host/)) dev=$2; if ($0~/\)\:/) {print $2,$1,fw, dev} }' OFS="|" test_data

I would like to turn it into a script. When doing so...

#!/bin/sh
awk '
BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} 
{
    if ($0~/sh failover/) fw=$1 ; 
    if (($0~/This host/)||($0~/Other host/)) dev=$2; 
    if ($0~/\)\:/) {
        print $2,$1,fw, dev
        } 
}' test_data 

...the F='[)#/(:]' results in an error.

[...srv01]$ ./test
./test: line 3: syntax error near unexpected token `)'
./test: line 3: `BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} '
[...srv01]$ 

When changing to double quotes it takes everything between the twp double quotes as separator so will look for )#/(: instead of ) or # or / or ( or :

Here is the file content of test_data

[...srv01]$ cat test_data
JoeASA# sh failover | i \)\:|host
        This host: Primary - Active
                  admin Interface management (313.13.0.13): Normal (Monitored)
                  DMZ-FW Interface Inside (310.13.19.7): Normal (Not-Monitored)
                  DMZ-FW Interface Outside-Zone2 (912.168.119.7): Normal (Not-Monitored)
                  ENET Interface OUTSIDE(912.168.191.7): Normal (Not-Monitored)
                  ENET Interface dmarc (912.168.192.7): Normal (Not-Monitored)
                  GW Interface Extranet (912.168.23.27): Normal (Not-Monitored)
                  GW Interface Outside-Zone (912.168.123.27): Normal (Not-Monitored)
                  GW Interface management (331.1.1.47): Normal (Not-Monitored)
        Other host: Secondary - Standby Ready
                  admin Interface management (313.13.0.12): Normal (Monitored)
                  DMZ-FW Interface Inside (310.13.19.6): Normal (Not-Monitored)
                  DMZ-FW Interface Outside-Zone2 (912.168.119.6): Normal (Not-Monitored)
                  ENET Interface OUTSIDE(912.168.191.6): Normal (Not-Monitored)
                  ENET Interface dmarc (912.168.192.6): Normal (Not-Monitored)
                  GW Interface Extranet (912.168.23.26): Normal (Not-Monitored)
                  GW Interface Outside-Zone (912.168.123.26): Normal (Not-Monitored)
                  GW Interface management (331.1.1.46): Normal (Not-Monitored)          
SIMPLEASA1/sec/act#  sh failover | i \)\:|host
        This host: Secondary - Active
                  Interface Edge (912.168.22.17): Normal (Monitored)
                  Interface Inside (310.13.19.17): Normal (Monitored)
                  Interface EXT (912.168.50.17): Normal (Monitored)
                  Interface WIFI (912.168.11.17): Normal (Monitored)
        Other host: Primary - Standby Ready
                  Interface Edge (912.168.22.16): Normal (Monitored)
                  Interface Inside (310.13.19.16): Normal (Monitored)
                  Interface EXT (912.168.50.16): Normal (Monitored)
                  Interface WIFI (912.168.11.16): Normal (Monitored)                      
[..srv01]$ 
  • 2
    Using double quotes is correct, but the input field separator variable is FS, not F. It's unclear why you suddenly set FS to a newline and why you set RS to an empty string. This is not what your first command uses. – Kusalananda Mar 17 at 16:35
  • Thanks! This was it....I needed that clarification with the FS (field separator). RS was just leftover from editing and trying different things. – peti27 Mar 18 at 0:43
1

You're passing the script to awk as a single-quoted string from the shell, but you seem to have single quotes inside the script, too. They actually end the quoted string:

awk 'BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} 
                ^^^^^^^ not quoted

The shell sees an unquoted ), which causes a syntax error. Not that you'd want to use single quotes in the awk script anyway, they would be a syntax error in awk. So use double-quotes instead, as you did for the other assignments, they fit inside single-quotes in the shell nicely, and actually work in awk code:

awk 'BEGIN { foo="bar"; ...}'

Then, note that what the -F option to awk, does is to set the field separator, which is the variable FS, not F. So, you want to have BEGIN { FS="[)#/(:]"; ..., and you probably don't want to change the default record separator RS either — at least you didn't change it in your one-liner above.


Also, instead of putting an awk script inside a shell script, you could just skip the shell, and make awk the interpreter of that script directly (assuming your awk is at /usr/bin/awk):

#!/usr/bin/awk -f
BEGIN { FS="[)#/(:]"; OFS="|"; fw=""; dev=""} 
{
    if ( $0 ~ /sh failover/ ) fw=$1 ; 
    if (($0 ~ /This host/) || ($0 ~ /Other host/)) dev=$2; 
    if ( $0 ~ /\)\:/ ) {
        print $2, $1, fw, dev
    } 
}

If that's called ./script.awk and made executable, you can then run it as ./script.awk filename, i.e. with the file to process as argument to the script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.