45

In this answer,

awk '$2=="no"{$3="N/A"}1' file

was accepted. Note the 1 at the end of the AWK script. In the comments, the author of the answer said

[1 is] a cryptic way to display the current line.

I'm puzzled. How does that work?

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • 3
    You may have a look at this page: http://backreference.org/2010/02/10/idiomatic-awk/ – Håkon Hægland Nov 28 '13 at 10:14
  • 1
    and this one: http://www.catonmat.net/blog/ten-awk-tips-tricks-and-pitfalls/ – Håkon Hægland Nov 28 '13 at 10:17
  • 2
    I did down vote this question, since this has been asked over and over. Just do a google search or reading any basic information about `awk` – Jotne Nov 28 '13 at 10:47
  • 2
    [For many people] stackoverflow makes it much easier to find answers than lengthy articles and forum discussions etc. So no matter how often the question is answered elsewhere, a stackoverflow post still adds value. – Aaron Campbell Nov 03 '16 at 20:56
  • 2
    I up vote this question, since Google moves right here. – it3xl Oct 25 '17 at 06:44

4 Answers4

49

In awk,

Since 1 always evaluates to true, it performs default operation {print $0}, hence prints the current line stored in $0

So, awk '$2=="no"{$3="N/A"}1' file is equivalent to and shorthand of

awk '$2=="no"{$3="N/A"} {print $0}' file

Again $0 is default argument to print, so you could also write

awk '$2=="no"{$3="N/A"} {print}' file

In-fact you could also use any non-zero number or any condition which always evaluates to true in place of 1

jkshah
  • 11,387
  • 6
  • 35
  • 45
12

The documentation says

In an awk rule, either the pattern or the action can be omitted, but not both. If the pattern is omitted, then the action is performed for every input line. If the action is omitted, the default action is to print all lines that match the pattern.

So, it treats 1 as pattern with no action. The default action is to print the line.

Even if you have a couple of rules, like in

awk '
    in_net {
        if (/^\s+bindIp:/) {
            print "  bindIp: 0.0.0.0"
            next
        } else if (/^\s*(#.*)?$/) {
            in_net = 0
        }
    }
    /^net:/ {
        in_net = 1
    }
    1
' /etc/mongod.conf

You still need 1, since default action is triggered only when encountering rule with no action.

x-yuri
  • 16,722
  • 15
  • 114
  • 161
2

AWK works on method of condition and then action. So if any condition is TRUE any action which we mention to happen will be executed then.

In case of 1 it means we are making that condition TRUE and in this case we are not mentioning any action to happen, so awk's by default action print will happen.

So this is why we write 1 in shortcut actually speaking.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
0

I thought I’d add an answer that explains how this shorthand works in terms of the POSIX specification for awk:

Basic description:

An awk program is composed of pairs of the form:

pattern { action }

Missing action:

Either the pattern or the action (including the enclosing brace characters) can be omitted. A missing pattern shall match any record of input, and a missing action shall be equivalent to:

{ print }

Description of pattern

A pattern is any valid expression

Description of Expression patterns:

An expression pattern shall be evaluated as if it were an expression in a Boolean context. If the result is true, the pattern shall be considered to match, and the associated action (if any) shall be executed.

Boolean context:

When an expression is used in a Boolean context, if it has a numeric value, a value of zero shall be treated as false and any other value shall be treated as true. Otherwise, a string value of the null string shall be treated as false and any other value shall be treated as true.


In the example of awk '$2=="no"{$3="N/A"}1', the pattern of the first pair is $2=="no" with a corresponding action of $3="N/A". This leaves 1 by itself as the next “pair” (pattern without a corresponding action).

Instead of 1, this lone expression pattern could be any numeric value or non-empty string, e.g.,

awk 9999
awk '"string"'

The awk 1 short-hand is fine when typing one-liners in an interactive shell. On the other hand, when writing scripts, I prefer my code to be more maintainable and readable for others by using the more explicit awk '{ print }'.

Anthony Geoghegan
  • 11,533
  • 5
  • 49
  • 56