1826073 Members
3445 Online
109690 Solutions
New Discussion

Re: scripting help

 
SOLVED
Go to solution
lawrenzo_1
Super Advisor

scripting help

here is the data I want to format:

lsdev -dev ent10 -attr
attribute value description user_settable

adapter_names ent3,ent7 EtherChannel Adapters True
alt_addr 0x000000000000 Alternate EtherChannel Address True
auto_recovery yes Enable automatic recovery after failover True
backup_adapter NONE Adapter used when whole channel fails True
hash_mode default Determines how outgoing adapter is chosen True
mode 8023ad EtherChannel mode of operation True
netaddr 0 Address to ping True
noloss_failover yes Enable lossless failover after ping failure True
num_retries 3 Times to retry ping before failing True
retry_time 1 Wait time (in seconds) between pings True
use_alt_addr no Enable Alternate EtherChannel Address True
use_jumbo_frame no Enable Gigabit Ethernet Jumbo Frames True

my code is as follows:

${PREFIX} lsdev -dev ent10 -attr |awk -v ENT=${ENT} -v SLOT=${SLOT} 'BEGIN{OFS=":"}

/^adapter_names/ { split($2,a,","); EN1 = a[1]; EN2 = a[2]; EN=$2 }
/^backup_adapter/ { BACKUP = $2}
/^mode/ { MODE = $2}
{if ( MODE == "8023ad" )} END{print "ETCN",ENT,MODE,EN1,EN2}'

This works and gives me the following output:

ETCN:ent10:8023ad:ent3:ent7

the problem I have is on some systems the mode is standard therefor I have to change the output:

lsdev -dev ent39 -attr
attribute value description user_settable

adapter_names ent36 EtherChannel Adapters True
alt_addr 0x000000000000 Alternate EtherChannel Address True
auto_recovery yes Enable automatic recovery after failover True
backup_adapter ent37 Adapter used when whole channel fails True
hash_mode default Determines how outgoing adapter is chosen True
mode standard EtherChannel mode of operation True
netaddr Address to ping True
num_retries 3 Times to retry ping before failing True
retry_time 1 Wait time (in seconds) between pings True
use_alt_addr no Enable Alternate EtherChannel Address True
use_jumbo_frame no Enable Gigabit Ethernet Jumbo Frames True

from the above I need to print:

{if ( MODE == "standard" )} END{print "ETCN",ENT,MODE,EN,BACKUP}'

I just cant seem to get the if or else sytax to work.

Any help would be greatly appreciated and appologies if this isnt clear ....

Thanks

Chris.
hello
10 REPLIES 10
Dennis Handly
Acclaimed Contributor
Solution

Re: scripting help

>{if ( MODE == "8023ad" )} END{print "ETCN",ENT,MODE,EN1,EN2}'

Don't format it like that, it is confusing. Use:
{
if ( MODE == "8023ad" ) print $0
}
END{print "ETCN",ENT,MODE,EN1,EN2}'

If you want to add another test, you can use else or "goto" style programming with next.
BEGIN{OFS=":"}
/^adapter_names/ { split($2,a,","); EN1 = a[1]; EN2 = a[2]; EN=$2 }
/^backup_adapter/ { BACKUP = $2}
/^mode/ { MODE = $2}
{
if ( MODE == "8023ad" ) {
do something?
} else if ( MODE == "standard" ) {
do something else?
}
}
END{print "ETCN", ENT, MODE, EN, BACKUP}'

So with this template, what do you want do do?
James R. Ferguson
Acclaimed Contributor

Re: scripting help

Hi Chris:

To add to Dennis's comment about "goto"s:

Awk (and Perl) offer the 'next' statement. This can greatly simplify and clarify processing. In 'awk' the 'next' statement causes processing of the current record to stop without honoring any other rules. The "next" record is then read. Perl uses 'next' in this fashion too.

If you use GNU 'awk' ['gawk'] you also have the 'nextfile' statement. As you might imagine, this causes flow to skip immediately to the next _file_. This is quite handy if you want to parse a series of files passed on the command line, but only want to process some of each files first few records.

Regards!

...JRF...
lawrenzo_1
Super Advisor

Re: scripting help

OK thanks dennis,

I am looking for

if ( MODE == "8023ad" ) {
print "ETCN",ENT,MODE,EN1,EN2
} else if ( MODE == "standard" ) {
print "ETCN",ENT,MODE,EN,BACKUP

so I am looking to print a different output depending on the mode.

is there a way I can assign the variables to an OUTPUT VAR and print that at the end ie:

if ( MODE == "8023ad" ) {
OUTPUT = ENT,MODE,EN1,EN2
} else if ( MODE == "standard" ) {
OUTPUT = ENT,MODE,EN,BACKUP
}
}
END{print "ENTH",OUTPUT}'


Chris.
hello
James R. Ferguson
Acclaimed Contributor

Re: scripting help

Hi Chris:

> is there a way I can assign the variables to an OUTPUT VAR and print that at the end?

Most certainly. By example:

# awk 'BEGIN{OUTPUT="ENT,MODE,EN1,EN2"};END{print "-->",OUTPUT}' /dev/null

Regards!

...JRF...

lawrenzo_1
Super Advisor

Re: scripting help

almost got it but feel like I've fudged the VAR substitution with the OFS:

${PREFIX} lsdev -dev ent10 -attr |awk -v ENT=${ENT} -v SLOT=${SLOT} '
BEGIN{OFS=":"}
/^adapter_names/ { split($2,a,","); EN1 = a[1]; EN2 = a[2]; EN=$2 }
/^backup_adapter/ { BACKUP = $2}
/^mode/ { MODE = $2}
{
if ( MODE == "8023ad" ) {
OUTPUT = ENT":"MODE":"EN1":"EN2
} else if ( MODE == "standard" ) {
OUTPUT = ENT":"MODE":"EN":"BACKUP
}
}
END{print "ETCH:"OUTPUT}'

ETCH:ent10:8023ad:ent3:ent7
hello
lawrenzo_1
Super Advisor

Re: scripting help

ok got that james - I'll give it a whirl ...
hello
Hein van den Heuvel
Honored Contributor

Re: scripting help



>> is there a way I can assign the variables to an OUTPUT VAR and print that at the end ie:

if ( MODE == "8023ad" ) {
OUTPUT = ENT,MODE,EN1,EN2

Yeah, easy. Should be:

OUTPUT = ENT FS MODE FS EN1 FS EN2

The FS stands for Field-Seperator and is what would have been used by the PRINT statement.

Standalone example:

$ awk 'BEGIN { a = "AAA"; b = "BBB"; test = a FS b FS a ; print test }'
AAA BBB AAA

Without FS it would look like:

$ awk 'BEGIN { a = "AAA"; b = "BBB"; test = a b a ; print test }'
AAABBBAAA

Hein.

James R. Ferguson
Acclaimed Contributor

Re: scripting help

Hi (again) Chris:

You have (greatly reduced):

# awk -v ENT="ent" -v SLOT="slot" 'BEGIN{OFS=":"};END{print ENT,SLOT}' /dev/null
ent:slot

...and one way to rectify this is:

awk -v ENT="ent" -v SLOT="slot" 'BEGIN{OFS=":"};END{printf("%s %s\n",ENT,SLOT)}' /dev/null
ent slot

...or any formatted output you want.

Regards!

...JRF...
lawrenzo_1
Super Advisor

Re: scripting help

ok thanks all,

I now have what I need using a variation of your examples and education:

${PREFIX} lsdev -dev ent10 -attr |awk -v ENT=${ENT} -v SLOT=${SLOT} '
BEGIN{OFS=":"}
/^adapter_names/ { split($2,a,","); EN1 = a[1]; EN2 = a[2]; EN=$2 }
/^backup_adapter/ { BACKUP = $2}
/^mode/ { MODE = $2}
{
if ( MODE == "8023ad" ) {
OUTPUT=ENT OFS MODE OFS EN1 OFS EN2
} else if ( MODE == "standard" ) {
OUTPUT = ENT OFS MODE OFS EN OFS BACKUP
}
}
END{printf("%s\n","ETCH:" OUTPUT)}'
ETCH:ent10:8023ad:ent3:ent7

although $SLOT is not used here.

Thanks all the same - whats life if you dont learn something new each day

:-)

Chris.

hello
lawrenzo_1
Super Advisor

Re: scripting help

.
hello