2

In the second awk one liner , I simply switched the < for > and it gave me a syntax error. Are we not allowed to use > in conditional statements?

~/Desktop $ awk 'BEGIN{print 3<5 ? "Hello":"World"}'
Hello
~/Desktop $ 
~/Desktop $ awk 'BEGIN{print 3>5 ? "hello": "world"}'
awk: cmd. line:1: BEGIN{print 3>5 ? "hello": "world"}
awk: cmd. line:1:                 ^ syntax error
~/Desktop $
~/Desktop $ awk 'BEGIN{print 5<3 ? "Hello":"World"}'
World
~/Desktop $
~/Desktop $
0

3 Answers 3

5

The print statement in awk takes one of three forms:

  • print > expression
  • print >> expression
  • print | expression

... where the >, >>, and | bit, and the expression that follows, are optional.

The print > expression command will cause the output to go to a file named by whatever string that expression evaluates to. If the file exists, it will be truncated (emptied). This is similar to how output redirection in the shell works, but the file will not be truncated by executing the same print statement a second time, unless close(expression) is used to close the file related to expression first.

The >> and | forms of the print command are also inspired by how the shell handles these tokens but see an awk manual for further information about these forms.

In your code, you have

print 3 > 5 ? "Hello" : "World"

This matches the print > expression syntax and would therefore output the string 3 to a file called 5. The rest of that line continues with a question mark, which your awk can't make much sense out of, so it complains about it. Some awk implementations would use the 5 ? "Hello" : "World" bit as the expression and would therefore write 3 to a file called Hello (since 5 is a true value when used as a boolean).

What you most likely wanted to do is

print ( 3 > 5 ? "Hello" : "World" )

or

print ( 3 > 5 ) ? "Hello" : "World"

This ensures that the print > expression syntax isn't triggered.

1
  • FWIW in GNU awk there's a 4th form of print which is print |& for communicating with a coprocess.
    – Ed Morton
    Aug 30, 2021 at 13:19
2

Use text only for your demos.

Use parentheses around your expression:

$ awk 'BEGIN{print (5>3 ? "Hello":"World")}'
Hello
$ awk 'BEGIN{print (3>5 ? "Hello":"World")}'
World

May be, > character is interpreted like a redirection to a file for print command

1
  • 1
    Note that with BEGIN{print 3>5 ? "Hello":"World"}, mawk and busybox awk do write 3 to the file called Hello, while some others need BEGIN{print 3>(5 ? "Hello":"World")} for that. Aug 30, 2021 at 5:34
1

Your code has an unparenthesized ternary expression [possibly] on the right side of output redirection. There are 2 issues with that:

  • An unparenthesized expression on the right side of output (or input) redirection is undefined behavior per POSIX so never do that.
  • An uparenthesized ternary expression is harder to read than one with parentheses and can lead to syntax errors in some awks in some contexts so never do that either.

Bad:

print > foo bar
getline < foo bar
str = x>y ? foo : bar

Good:

print > (foo bar)
getline < (foo bar)
str = (x>y ? foo : bar)

When creating multiple output files, though, it's usually a good idea to close them as you go and then you would store the output file name that's the result of the expression in a variable and then you don't need parens, e.g.:

out = foo bar
print > out
close(out)

So your code:

awk 'BEGIN{print 3<5 ? "Hello" : "World"}'
awk 'BEGIN{print 3>5 ? "hello" : "world"}'
awk 'BEGIN{print 5<3 ? "Hello" : "World"}'

which, depending on what it's supposed to do, is either not using parens on the right side of output redirection or not using parens around a ternary or both and so should instead be written as:

awk 'BEGIN{print (3<5 ? "Hello" : "World")}'
awk 'BEGIN{print (3>5 ? "hello" : "world")}'
    or, less likely, awk 'BEGIN{print 3 > (5 ? "hello" : "world")}'
awk 'BEGIN{print (5<3 ? "Hello" : "World")}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.