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 SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multiple if with one else syntax 1

Status
Not open for further replies.

madasafish

Technical User
Jul 18, 2006
78
0
0
TH
Code:
gawk 'BEGIN {}
        !/btvtracker/ { next }
{
        split (substr ($12,50),a,"&");clickthru=a[1];etvchannel=a[2]
        split (etvchannel,b,"=");chantype=b[1];channo=b[2]
        x[channo","clickthru]++
}

END     {
                for (y in x) {
                split (y,c,",");i=c[1];j=c[2]
                vchanname=etvchannel

                if (i=="101") { vchanname="BBC One"; }
                if (i=="102") { vchanname="BBC Two" }
                if (i=="203") { vchanname="ITV 1" }
                if (i=="304") { vchanname="Channel 4" }
                if (i=="405") { vchanname="Five" }
                if (i=="506") { vchanname="BBC 3" }
                if (i=="607") { vchanname="BBC 4 " }
                if (i=="808") { vchanname="BBC ONE HD" }
                # etc.......
                
                #else { continue }
                print i","vchanname","j","x[y]
               }


}' ${FILE} | sort -n >>  ${WEBDIR}/${SITE}.${REPDATE}.csv

The code above produces count of http hits from a large apache access log. It works but includes "i" numbers that I am not interested in which is why I am trying to use the "else" to filter out "i" numbers that I am not interested in. I have tried different permutations of placing the the brackets {} but cannot get the code to read the if statements as one block with the one following else. I have tried using "else if" as well but to no avail. Can someone please assist in providing the correct syntax?

For the more learned among you, I am not that keen on hard coding the TV names within the gawk program and would ideally like to have a seperate master file that held the names and the gawk program did a lookup to that file.

For example the master file would like this...
101,BBC One
102,BBC Two
203,ITV 1
304,Channel 4
405,Five
etc....

As always,

Thanks in advance

Madasafish

 
Hi

Madasafish said:
I have tried using "else if" as well but to no avail.
How ? That is what you need.
Code:
[b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"101"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"BBC One"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"102"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"BBC Two"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"203"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"ITV 1"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"304"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"Channel 4"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"405"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"Five"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"506"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"BBC 3"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"607"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"BBC 4"[/i][/green]
[b]else[/b] [b]if[/b] [teal]([/teal]i[teal]==[/teal][green][i]"808"[/i][/green][teal])[/teal] vchanname[teal]=[/teal][green][i]"BBC ONE HD"[/i][/green]
[b]else[/b] [b]continue[/b]
But would be much better to avoid all those [tt]if[/tt]s by using an array :
Code:
BEGIN [teal]{[/teal]
  chanlist[teal][[/teal][green][i]"101"[/i][/green][teal]]=[/teal][green][i]"BBC One"[/i][/green]
  chanlist[teal][[/teal][green][i]"102"[/i][/green][teal]]=[/teal][green][i]"BBC Two"[/i][/green]
  chanlist[teal][[/teal][green][i]"203"[/i][/green][teal]]=[/teal][green][i]"ITV 1"[/i][/green]
  chanlist[teal][[/teal][green][i]"304"[/i][/green][teal]]=[/teal][green][i]"Channel 4"[/i][/green]
  chanlist[teal][[/teal][green][i]"405"[/i][/green][teal]]=[/teal][green][i]"Five"[/i][/green]
  chanlist[teal][[/teal][green][i]"506"[/i][/green][teal]]=[/teal][green][i]"BBC 3"[/i][/green]
  chanlist[teal][[/teal][green][i]"607"[/i][/green][teal]]=[/teal][green][i]"BBC 4"[/i][/green]
  chanlist[teal][[/teal][green][i]"808"[/i][/green][teal]]=[/teal][green][i]"BBC ONE HD"[/i][/green]
[teal]}[/teal]

[gray]# then later in place of those ifs[/gray]
  [b]if[/b] [teal]([/teal]i [teal]in[/teal] chanlist[teal])[/teal] vchanname[teal]=[/teal]chanlist[teal][[/teal]i[teal]][/teal]
  [b]else[/b] [b]continue[/b]
Of course this is still ugly practice. You should store the channel list in a separate data file to avoid all those assignments to chanlist array items :
Code:
BEGIN [teal]{[/teal]
  [blue]FS[/blue][teal]=[/teal][green][i]"[/i][/green][lime][i]\t[/i][/lime][green][i]"[/i][/green]
  [b]while[/b] [teal]([/teal][COLOR=chocolate]getline[/color] [teal]<[/teal] [green][i]"channellist.txt"[/i][/green][teal])[/teal]
    chanlist[teal][[/teal][navy]$1[/navy][teal]]=[/teal][navy]$2[/navy]
  [COLOR=chocolate]close[/color][teal]([/teal][green][i]"channellist.txt"[/i][/green][teal])[/teal]
  [blue]FS[/blue][teal]=[/teal][green][i]" "[/i][/green]
[teal]}[/teal]

[gray]# the checking part remains the same[/gray]
  [b]if[/b] [teal]([/teal]i [teal]in[/teal] chanlist[teal])[/teal] vchanname[teal]=[/teal]chanlist[teal][[/teal]i[teal]][/teal]
  [b]else[/b] [b]continue[/b]
Code:
101	BBC One
102	BBC Two
203	ITV 1
304	Channel 4
405	Five
506	BBC 3
607	BBC 4
808	BBC ONE HD
After this you can add/remove/change channels without the need to modify the Awk code.

Feherke.
 
Thank-you Feherke for an excellent explanation, it worked a treat.

Can I take this one step further.....?

I want to include genre's as the 3rd column of the channellist.txt file. Please note I have changed the Field seperator to "," eg:

Code:
428,Film4,Movies
434,Sky Comedy,Comedy
511,Sky Sports,Sports
232,Nat Geo HD,Factual 
etc...

I have tried variations of the getline section
Code:
chanlist[$1,$2,$3]=$1,$2,$3

If I use "print i,chanlist" it does print out but not in the order I want.
When I try to split chanlist and then print the split fields it does not work.
Ultimately, I am trying to print out...

print i","vchanname","j","x[y]","chanlist[$3]

If it is possible to access individual fields in a getline array.

As always thanks in advance,

Madasafish

 
Hi

As I understand, your input data will still be that channel number/ID/code, so the chanlist array's indices should be the same $1.

Furthermore, the comma ( , ) is recognized ( and practically replaced with [tt]SUBSEP[/tt] ) only in array subscript to emulate multidimensional arrays. So the commas in the right side values are syntactically invalid.

Given the above, the closest would be to store the data in a two dimensional array :
Code:
chanlist[teal][[/teal][navy]$1[/navy][teal],[/teal][green][i]"name"[/i][/green][teal]]=[/teal][navy]$2[/navy]
chanlist[teal][[/teal][navy]$1[/navy][teal],[/teal][green][i]"genre"[/i][/green][teal]]=[/teal][navy]$3[/navy]
In case of "428,Film4,Movies" this would be syntactically equivalent with :
Code:
chanlist[teal][[/teal][purple]428[/purple][teal],[/teal][green][i]"name"[/i][/green][teal]]=[/teal][green][i]"Film4"[/i][/green]
chanlist[teal][[/teal][purple]428[/purple][teal],[/teal][green][i]"genre"[/i][/green][teal]]=[/teal][green][i]"Movies"[/i][/green]
But because of the way comma is handled and multidimensional arrays are emulated, this would be practically equivalent with :
Code:
chanlist[teal][[/teal][green][i]"428[/i][/green][lime][i]\034[/i][/lime][green][i]name"[/i][/green][teal]]=[/teal][green][i]"Film4"[/i][/green]
chanlist[teal][[/teal][green][i]"428[/i][/green][lime][i]\034[/i][/lime][green][i]genre"[/i][/green][teal]]=[/teal][green][i]"Movies"[/i][/green]
Not a joy to iterate over it.

If you have [tt]gawk[/tt] 4 or newer, you can use real multidimensional array :
Code:
chanlist[teal][[/teal][navy]$1[/navy][teal]][[/teal][green][i]"name"[/i][/green][teal]]=[/teal][navy]$2[/navy]
chanlist[teal][[/teal][navy]$1[/navy][teal]][[/teal][green][i]"genre"[/i][/green][teal]]=[/teal][navy]$3[/navy]
That way the iterating will not be compromised.

For a portable way, better use two arrays :
Code:
chanlist[teal][[/teal][navy]$1[/navy][teal]]=[/teal][navy]$2[/navy]
genrelist[teal][[/teal][navy]$1[/navy][teal]]=[/teal][navy]$3[/navy]


Feherke.
[link feherke.github.com/][/url]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top