Help a newbie please with awk if else statements


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Help a newbie please with awk if else statements
# 1  
Old 10-07-2008
Help a newbie please with awk if else statements

Hi,

Despite reading the Conditional Statements chapter in the O'Reilly Sed & Awk book several times and looking at numerous examples, I cannot for the life of me get any kind of if ... else statement to work in my awk scripts! My scripts work perfectly (as they are written at least) and do what they should until I add any if statement(s), at which point I just get syntax errors at every 'if' and every 'else'.

Can anyone shed some light on this please? I am using gawk in DOS under Windows XP Pro SP3 (not my choice of OS, but it pays the bills).

Code:
BEGIN {FS="[ \t]*,[ \t]*";
  OFS=",";
  print "Finding good records..." 
 }
NR == 1 { new_fname = gensub(/\.csv$/, "", 1, FILENAME) "_good.csv"; }
$36 ~ /N/ { for (i = 1; i<= NF; i++) {
   gsub(/^ /, "", $i);
   gsub(/ $/, "", $i);
   gsub(/"/, "", $i);
   }
  }
output = ""
 
output = sprintf ("%s,%s,%s", $1, $38, $39);
 
if ( $40 == /^ / && $41 == /^ / ) {
  output = sprintf("%s,%s,%s,%s,", output, $42, $43, $44);
  }
 else {
  output = sprintf("%s,%s,%s,%s,%s,%s,", output, $40, $41, $42, $43, $44);
  }
 
if ( $55 ~ /MR|MISS|MS|MRS/ ) { 
  output = sprintf("%s, %s %s %s %s", output, $59, $55, $56, $57, $58);
  }
 else if ( $55 ~ /Applicant/ && !$58 ) {
  output = sprintf("%s, %s %s %s %s", output, $60, $56, $57, $58, $59);
  }
 
 
END {  
  printf("%s\n",output);
  print "Finished!  Output sent to '"new_fname"'"
  }

Basically I am parsing a csv file which has a few empty fields (they are always in the same place, but are not on every line) that I wish to capture and remove from the output, this is what the if ... else statements do. I have tried other methods but this seems like the best (or only) way to do it, combined with sprintf.
# 2  
Old 10-07-2008
An explicit if/else can appear only inside an action block { ... }.
Could you post sample input and the desired output?
# 3  
Old 10-07-2008
See the bolded remarks I put in the snippets of your code.

Quote:
Originally Posted by jonathanm
Code:
$36 ~ /N/ { for (i = 1; i<= NF; i++) {
   gsub(/^ /, "", $i);
   gsub(/ $/, "", $i);
   gsub(/"/, "", $i);
   }
  }
  ^-- this is (probably) wrong. You want to end the block below
output = ""
 
... 

 else if ( $55 ~ /Applicant/ && !$58 ) {
  output = sprintf("%s, %s %s %s %s", output, $60, $56, $57, $58, $59);
  }
 
}
^-- you need to finish the block here
 
END {  
  printf("%s\n",output);
  print "Finished!  Output sent to '"new_fname"'"
  }

# 4  
Old 10-07-2008
Looking at this again, I think you're confused about how awk works. Each line is compared to each pattern, in turn, and if there is a match, the "program" part (for each pattern that matches) is then run, in turn. After all input is consumed, THEN the "END" block is executed. To have one of these programs "skip" to the next line, use "next;". Further points:

1. I'm not sure what you are trying to do with the NR==1 line (you never write to new_fname). You can output to a file with "printf expr list >filename".

2. You're not using sprintf() in a meaningful way, except to avoid printing out a newline. You can just do "print $1, $38, $50", except that a newline will be appended. But I don't see why you're using it this way.

3. Instead of "END", you can have a "default" program at the end. Sometimes you have to give it an expression of "1". This way you can prepare your output and then have:

Code:
/pattern/ { program1 }
/pattern2/ { program 2 }
...
1 { print output >newfilename }

You can also put this at the beginning of the list of pattern-programs, and that way it will execute every time, regardless if a program uses "next". Here, however, you have to be sure that (1) you don't print out when there is nothing to print out, and (2) if you don't want to print out something, you empty the field.
Code:
length(output) { print output > newfilename } 

/badfield/ {  output=""; next; }
/goodfield/ { output=output "blah blah"; next; }
/other/ { output="fubar"; }
...

# 5  
Old 10-08-2008
Quote:
Originally Posted by otheus
Looking at this again, I think you're confused about how awk works. Each line is compared to each pattern, in turn, and if there is a match, the "program" part (for each pattern that matches) is then run, in turn. After all input is consumed, THEN the "END" block is executed. To have one of these programs "skip" to the next line, use "next;".
Just when I thought I was starting to get the hang of it too! Smilie

Quote:
1. I'm not sure what you are trying to do with the NR==1 line (you never write to new_fname). You can output to a file with "printf expr list >filename".
I am forming the output filename in a variable, changing the ending to "_good.csv". This works and I am happy with it.

Quote:
2. You're not using sprintf() in a meaningful way, except to avoid printing out a newline. You can just do "print $1, $38, $50", except that a newline will be appended. But I don't see why you're using it this way.
I am attempting to form my output line for each record according to some caveats, namely removing certain blank fields if they are present. I could not see any other way to do this except to use sprintf to add what I needed to my existing string, and then print that to the file. Just using "print $1, $38, $50" didn't catch the blank fields (and other special cases) as I needed it to.

Quote:
Code:
length(output) { print output > newfilename } 
 
/badfield/ {  output=""; next; }
/goodfield/ { output=output "blah blah"; next; }
/other/ { output="fubar"; }
...

I think I understand this part already, but it has helped me grasp the idea of program blocks and the way awk works. Thanks Smilie
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

awk with many if statements

Hi What is the right structure to use awk with multiple If statements The following code doesn't work # awk ' { A = $1 } END { for ( i = 1; i <= c; i++ ) { if ( A == 236 && A ==199... (7 Replies)
Discussion started by: khaled79
7 Replies

2. Shell Programming and Scripting

Nested awk Statements

Hello again everyone, yes, I'm back again for more help! So I'm attempting to read two separate files and generate some XML code from that. My current code is: BEGIN { print "<?xml version=\"1.0\" encoding=\"utf-8\">" print "<Export>" } { x=1; print "<section name=\"Query" NR "\">"... (5 Replies)
Discussion started by: Parrakarry
5 Replies

3. Shell Programming and Scripting

awk problem - combining awk statements

i have a datafile that has several lines that look like this: 2,dataflow,Sun Mar 17 16:50:01 2013,1363539001,2990,excelsheet,660,mortar,660,4 using the following command: awk -F, '{$3=strftime("%a %b %d %T %Y,%s",$3)}1' OFS=, $DATAFILE | egrep -v "\-OLDISSUES," | ${AWK} "/${MONTH} ${DAY}... (7 Replies)
Discussion started by: SkySmart
7 Replies

4. UNIX for Dummies Questions & Answers

Combine two awk statements into one

Hi, I have the following two awk statements which I'd like to consolidate into one by piping the output from the first into the second awk statement (rather than having to write kat.txt out to a file and then reading back in). awk 'BEGIN {FS=OFS=" "} {printf("%s ", $2);for (x=7; x<=10;... (3 Replies)
Discussion started by: kasan0
3 Replies

5. Shell Programming and Scripting

How to use awk or nawk by using Conditional Statements

Hi Guys! Anybody know how can I use a nawk or awk on a script and printing the NAME, SECTION (must be 410 or 411 or 414) and TOTAL COST of CLASS 1 and 3 combined must be greater than 50. See below desired output file. input.txt: NAME,CLASS,COST,SECTION JOHN,1,10,410 JOHN,2,20,410... (2 Replies)
Discussion started by: pinpe
2 Replies

6. UNIX for Dummies Questions & Answers

AWK w/ if statements failing.

I'm converting some code from ksh on my macbook (Version M 1993-12-28 s+) to an older solaris machine with ksh 88. I can't seem to figure out this line, it worked on the new shell version. set -A combo -- $(for x in ${ImageIDs}; do nawk -v s=$x 'if($2 == s) getline ; getline if ($1 ==... (2 Replies)
Discussion started by: nerdcurious
2 Replies

7. Shell Programming and Scripting

Combining AWK statements

Hello UNIX Community, I have file that contains the following data: testAwk2.csv rabbit penguin goat giraffe emu ostrich hyena elephant panda dog cat pig lizard snake antelope platypus tiger cheetah lion rhino spider I then find the character length of the... (1 Reply)
Discussion started by: vnayak
1 Replies

8. Shell Programming and Scripting

Combining awk statements

I have a pretty simple script below: #!/bin/sh for i in *.cfg do temp=`awk '/^InputDirectory=/' ${i}` input_dir=`echo ${temp} | awk '{ print substr( $0, 16) }'` echo ${input_dir} done As you can see its opening each cfg file and searching for the line that has "InputDirectory="... (3 Replies)
Discussion started by: ssbsts
3 Replies

9. Shell Programming and Scripting

Combine awk statements

I have an awk statement that works but I am calling awk twice and I know there has to be a way to combine the two statements into one. The purpose is to pull out just the ip address from loopback1. cat config.txt | nawk 'BEGIN {FS="\n"}{RS="!"}{if ( $0 ~ "interface loopback1" ) print$4}' | nawk... (5 Replies)
Discussion started by: numele
5 Replies

10. Shell Programming and Scripting

awk compound statements

how can i use two or multiple statements in the if part of an awk code for example i want to check two flag if they are true i will write some print operations and increase the counter. here is the c version of the code that i want to write: counter=0; if (flag1==1 && flag2==0) {... (7 Replies)
Discussion started by: gfhgfnhhn
7 Replies
Login or Register to Ask a Question