0

I am trying to retrive the status of the objects from the below output(the value of Name field and the value of OpState field corresponding to the same) using shell script.For example in the above output the status of 'DP-UID-FSH' is 'up'. I want to produce an output like:

Platform: Bash on Solaris.

DP-UID-FSH is up.
DP-Cert-FSH is up.

Below is the content of the file which nees to be parsed to produce above output.

<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>HTTPSSourceProtocolHandler</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>DP-UID-FSH</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>
<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>SLMAction</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>DP-Cert-FSH</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>
<ConfigState>saved</ConfigState></ObjectStatus><ObjectStatus     xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<Class>SLMAction</Class>
<OpState>up</OpState>
<AdminState>enabled</AdminState>
<Name>shape</Name>
<EventCode>0x00000000</EventCode>
<ErrorCode/>

saved

I am a newbee in shell script and doesnt have a clue on how this can be achieved?

user2607367
  • 225
  • 4
  • 25

2 Answers2

2

The Awk solutions have gotten messy so I'd just add another answer that uses Perl. I'm not well-versed in Perl but I learn easy and this could solve it as well:

perl -lane '$state = (split(/[<>]/))[2] if /OpState/; print ((split(/[<>]/))[2] . " is $state.") if /<Name>/' file

Output:

DP-UID-FSH is up.
DP-Cert-FSH is up.
shape is up.

As jaypal suggested (thanks), split is not needed since autosplit (-a) is enabled:

perl -F'[<>]' -lane '$state = $F[2] if /OpState/; print "$F[2] is $state" if /<Name>/' file
Community
  • 1
  • 1
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • It is working like a charm.Could you please explain the working of this script in brief? – user2607367 Jul 31 '14 at 12:18
  • It only processes lines containing `` and ``. When it finds ``, it extracts the value and saves it to a variable (`$state`). Next it should find `` and when it finds it, it would extract the value in it and at the same time along with `$state` it would print the message. – konsolebox Jul 31 '14 at 12:21
  • Could you please explain `(split(/[<>]/))[2]`? Is it a regular expression matching <> ? – user2607367 Jul 31 '14 at 12:29
  • It's well documented [here](http://perldoc.perl.org/functions/split.html). It splits the line (`$_`) with separators matching `/[<>]/` (`<` or `>`) into an array. `[2]` points to the third element that gets extracted after running the command. – konsolebox Jul 31 '14 at 12:32
  • Why do we want to extract the third element? We need to extract the second element in the array, i.e. `up` and `DP-UID-FSH` i.e. the value of `Name` and `OpState` field.isn't it? – user2607367 Jul 31 '14 at 12:43
  • @user2607367 It's the 3rd. One empty string before `<`, another between `<` and `>`, and third between `>` and the next `<`. – konsolebox Jul 31 '14 at 13:57
  • 2
    @konsolebox The `-a` option is for `autosplit` so it's not really doing anything here since you manually split the line later. An alternate would be `perl -F'[<>]' -lane '$state = $F[2] if /OpState/; print "$F[2] is $state" if //' file`. +1 coz I always appreciate `perl` solutions. `:)`. – jaypal singh Jul 31 '14 at 17:15
0

With GNU Awk or Mawk:

awk -v RS='<OpState>' -F '[<>]' 'NR > 1 { printf "%s is %s.\n", $9, $1 }' file

Another:

awk '/OpState/ { gsub(/<\/?OpState>/, ""); s = $0; } /<Name>/ { gsub(/<\/?Name>/, ""); printf "%s is %s.\n", $0, s; }' file

Yet another:

awk -F '[<>]' '/OpState/ { s = $3; } /<Name>/ { printf "%s is %s.\n", $3, s; }' file

Output:

DP-UID-FSH is up.
DP-Cert-FSH is up.
shape is up.
konsolebox
  • 72,135
  • 12
  • 99
  • 105
  • I am getting Syntax error while using this.I am running this in BASH shell on Solaris. `awk: syntax error near line 1 awk: bailing out near line 1` – user2607367 Jul 31 '14 at 11:11
  • @user2607367 Can you tell me your awk's version? `awk --version` – konsolebox Jul 31 '14 at 11:14
  • It's probably Nawk. My script is not compatible with it unfortunately. If you can install Gawk or Mawk to your system, you would be able to make it work. – konsolebox Jul 31 '14 at 11:16
  • `awk --version` is not producing any output – user2607367 Jul 31 '14 at 11:19
  • @user2607367 It's neither Gawk nor Mawk. – konsolebox Jul 31 '14 at 11:22
  • @user2607367 I added another solution. Please check. – konsolebox Jul 31 '14 at 11:35
  • tried the other solution. STill getting the syntax error. `awk: syntax error near line 1 awk: illegal statement near line 1 awk: syntax error near line 1 awk: illegal statement near line 1` – user2607367 Jul 31 '14 at 11:40
  • Well that's unfortunate sorry. The last suggestion I can give to you is the third version. Please check my update. I hope it works this time. – konsolebox Jul 31 '14 at 11:43
  • If it still doesn't work, best thing I could suggest is that you upgrade your awk like install gawk or mawk. You can also consider using other languages like perl. Perhaps you just need to update your post with more descriptions and tags. – konsolebox Jul 31 '14 at 11:45
  • This didnt work as well.Thanks for your help. i will update my question with more tags. – user2607367 Jul 31 '14 at 11:50
  • @user2607367 whenever you get that specific error message it means you are using old, broken awk (/usr/bin/awk on Solaris). Never use that awk. Since you tagged your question with Solaris, if you can't install gawk for some reason use /usr/xpg4/bin/awk or nawk instead. – Ed Morton Jul 31 '14 at 13:55