3

From the info below:

$ cat access.dat
2025/01/01T10:00:01 "GET" /path/resource/api1 User1 500
2025/01/01T10:00:01 "DELETE" /path/resource/api1 User1 503
2025/01/01T04:00:01 "GET" /path/resource/api1 User1 500
2025/01/01T03:00:01 "GET" /path/resource/api1 User1 503
2025/01/01T05:00:01 "PUT" /path/resource/api1 User2 500
2025/01/01T06:00:01 "GET" /path/resource/api1 User1 200
2025/01/01T07:00:01 "GET" /path/resource/api1 User1 201
2025/01/01T08:00:01 "GET" /path/resource/api2 User1 500
2025/01/01T09:00:01 "POST" /path/resource/api2 User2 500
2025/01/01T10:00:01 "POST" /path/resource/api2 User1 400
2025/01/01T11:00:01 "GET" /path/resource/api2 User2 404

I am trying to generate an awk script with if else statement. When doing

cat access.dat | awk '{if ($NF>=400) {print $0}} > failure.dat 

the output file is generated successfully. But when adding

cat access.dat | awk '{if ($NF>=400) {print $0} > failure.dat else {print$0} > success.dat}

is marking error. What is wrong in my awk script? How could I generate both failure.dat and success.dat inside if/else statement?

Thank you for your help.

2
  • 2
    Both your commands are invalid -- as shown, they have unbalanced 'quotes. Difficult to tell, but you appear to be mixing awk and shell syntax. In awk, (unquoted) failure, success and dat are (undefined) variables, not strings. I suspect awk is throwing syntax on the dot, or possibly even fatal: cannot redirect to . : Is a directory. Commented Feb 21 at 16:56
  • 2
    Get used to copy/pasting your shell commands into shellcheck.net until you get more familiar with Unix. Commented Feb 21 at 22:06

3 Answers 3

8

You need to quote the filenames to prevent awk to treat them as variables:

awk '{
    if ($NF>=400) {print > "failure.dat"}
    else {print > "success.dat"}
}' file

and you need to do the redirection inside the curly brackets.

You could also shorten it by using the ternary operator:

awk '{print > (($NF < 400 ? "success" : "failure")".dat")}'

(The outer parenthesis is needed in some awk implementations).

1
  • 1
    @STerliakov, my bad, there was a missing ) indeed. Commented Feb 22 at 16:42
5

Even clearer:

awk -v Ok=success.dat -v No=failure.dat '{ print > ($NF>=400 ? No : Ok) }' access.dat
0
4

Your syntax is odd. I don't understand why you have the > outside the { } block. This is a more natural (IMO, anyway) way of writing it:

awk '{if ($NF>=400) print > "failure.dat"; else print > "success.dat"}' access.dat

Or, a bit more clearly:

awk '
{ 
  if ($NF>=400)
    print > "failure.dat"
   
  else
    print > "success.dat"
}' access.dat

And, just for fun, less clearly but more concisely:

awk '{k = $NF>=400 ? "failure.dat" : "success.dat"; print > k}' access.dat
0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.