1827807 Members
3041 Online
109969 Solutions
New Discussion

Re: Awk help

 
SOLVED
Go to solution
cbres00
Frequent Advisor

Awk help

I need to redirect awk output depending on how many pipes I find in a file. Logic would go like this:

awk 'BEGIN { FS="|"; OFS="|" }
{ (if NF = 4 )
{ print $0 } > good_file.txt
else
{ print $0 } > bad_file.txt
} < input_file.txt

I keep getting the cryptic awk "something wrong on line 3" message. What am I missing here?

Regards,
CB




Life is too short not to have fun every single day
16 REPLIES 16
A. Clay Stephenson
Acclaimed Contributor

Re: Awk help

The first thing that jumps out at me is
if (NF = 4)
I assume you meant a comparison rather than an assignment. Use "==".
If it ain't broke, I can fix that.
cbres00
Frequent Advisor

Re: Awk help

Yes. I still get an error msg on line 3, however.
Life is too short not to have fun every single day
A. Clay Stephenson
Acclaimed Contributor

Re: Awk help

Okay, I see a beginning single-quote but no terminal single-quote.
If it ain't broke, I can fix that.
cbres00
Frequent Advisor

Re: Awk help

Sorry....i have that in there, too. ;-)

Is my syntax correct for the 'if' statement?
I've tried restructuring this several ways but still no success. Obviously I haven't hit the right way.

CB
Life is too short not to have fun every single day
Hein van den Heuvel
Honored Contributor

Re: Awk help

man awk...
print [expression-list] [ > expression]

So you need to (double)quote file.txt to make it an expression. And you have the closing curly brace in the wrong place.
Try something like:


awk '{ if (NF==2) {print $0 >> "good_file.txt"} else {print $0 >> "bad_file.txt"}}'
aap
aap noot
aap noot mies
$ cat good_file.txt
aap noot
$ cat bad_file.txt
aap
aap noot mies

Hein.

A. Clay Stephenson
Acclaimed Contributor

Re: Awk help

Okay, I see a beginning single-quote but no terminal single-quote.

Next (if NF = 4) should be "if (NF == 4)".
No quotes around the filename:

awk 'BEGIN { FS="|"; OFS="|" }
{
if (NF == 4 ) print $0 > "good_file.txt"
else print $0 > "bad_file.txt"
}' < input_file.txt

should be close.
If it ain't broke, I can fix that.
H.Merijn Brand (procura
Honored Contributor

Re: Awk help


# perl -aF\\\| -pe'select@F==4?STDOUT:STDERR' input_file.txt >good_file.txt 2>bad_file.txt

or

# perl -aF\\\| -ne'print{@F==4?STDOUT:STDERR}$_' input_file.txt >good_file.txt 2>bad_file.txt

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
cbres00
Frequent Advisor

Re: Awk help

Hmmmm....still not working.
I also need to replace the file name with a variable but I'm not sure it would matter.

cb
Life is too short not to have fun every single day
A. Clay Stephenson
Acclaimed Contributor

Re: Awk help

Well, I just cut and pasted my last example and it worked. I won't suggest that your method are optimal but there should be no syntax errors.
If it ain't broke, I can fix that.
cbres00
Frequent Advisor

Re: Awk help

how would you optimize it?
Life is too short not to have fun every single day
A. Clay Stephenson
Acclaimed Contributor

Re: Awk help

The biggest change that I would make is passing in variables using multiple -vbadfile=bad_file.txt arguments to replace your hard-coded filenames. Awk is good at redirecting output. Surprisingly, 'print $0 > "filename"' is efficient because the file is not opened and closed each time the print executes -- at least until awk runs out of file descriptors. I always shudder when I see hard-coded names put in any script. Imagine the consequences of running two of your scripts simultaneously. You might find it better to let awk function as a filter so that the "good" output simply goes to stdout while the "bad" output goes to an error file, possibly stderr.
If it ain't broke, I can fix that.
cbres00
Frequent Advisor

Re: Awk help

See my post about three above this one!
Yes, I DO use variables....I have to.

;-)

cb
Life is too short not to have fun every single day
cbres00
Frequent Advisor

Re: Awk help

Argggghhh....
I decided to use nawk so I can find out what's exactly wrong here.

awk 'BEGIN { FS="|"; OFS="|" }
{ if ( NF = 12 )
{ print $0 } > ${tmp_file3}
else
{ print $0 } > ${tmp_file4}
}' < ${tmp_file2}

I get this error:
nawk: syntax error at source line 3
context is
{ print $0 } >>> > <<< ${tmp_file3}
nawk: illegal statement at source line 3
nawk: syntax error at source line 4

I also tried to put double quotes around the variable but that didn't work.

CB
Life is too short not to have fun every single day
Kent Ostby
Honored Contributor

Re: Awk help

I believe that this:
{ print $0 } > ${tmp_file3}
else
{ print $0 } > ${tmp_file4}

should read:

{ print $0 > ${tmp_file3} }
else
{ print $0 > ${tmp_file4} }

By including the "}" before the ">", you have effectively ended the print statement.

Best regards,

KEnt M. Ostby
"Well, actually, she is a rocket scientist" -- Steve Martin in "Roxanne"
john korterman
Honored Contributor
Solution

Re: Awk help

Hi,
I do not have a system available at the moment, but I think your problems derive from the use of the dollar sign, e.g.:
print $0 } > ${tmp_file3}
You cannot directly expand a shell variable in an awk script by a dollar sign, awk will not interpret thia as a shell variable.
You have to define which shell variables you want to use in your awk script, e.g.
awk -v FILE1=/tmp/flip -v FILE2=/tmp/flop 'rest of script in which you use the variables in awk without the dollar sign, e.g. print >FLIP'

regards,
John K.
it would be nice if you always got a second chance
cbres00
Frequent Advisor

Re: Awk help

You are indeed correct!! I had to put the ${tmp_file2} reference in double- then single-quotes (" ' ${tmp_file2} ' "). It works like a charm.

Thanks to all who helped me!

Cathy
Life is too short not to have fun every single day