What does a number do after curly braces?

前端 未结 2 486
花落未央
花落未央 2021-02-01 06:05

Why does

echo foo bar..baz bork | awk \'BEGIN{RS=\"..\"} {gsub(OFS,\"\\t\");}1\'

seem to do the same thing as

echo foo bar..baz         


        
相关标签:
2条回答
  • 2021-02-01 06:46

    If you remember, awk is a language which has a series of <pattern> <action> operations. Each pattern is evaluated for each line (at least conceptually), and when the pattern matches, the action is executed. Either the pattern or the action can be omitted. An omitted pattern matches every line; an omitted action defaults to {print $0} (aka {print}). The 'pattern' might be a simple regex match, or some other more complicated and general condition, which must evaluate to true if the action is to be executed (as noted by Ed Morton in his comment).

    In your example, the 1 is a pattern; it evaluates to true. The action is not specified, so the default action is invoked, which is {print} or {print $0}. Any value other than zero or an empty string evaluates to true and will invoke the print. (Note that if you mention an uninitialized variable (for example, c), then it is autocreated and set to zero and therefore evaluates to false. Hence awk 'c' <<<"Hi" prints nothing.)

    The actions associated with the BEGIN and END patterns are handled specially, of course.

    0 讨论(0)
  • 2021-02-01 06:46

    I really dislike these types of shortcuts because it obfuscates and misleads how it's being parsed. Like you said,

    awk 'BEGIN{RS=".."} {gsub(OFS,"\t");}1'
    

    seems to be equivalent to

    awk 'BEGIN{RS=".."} {gsub(OFS,"\t");} {print;}'
    

    which would seem to imply that 1 is simply an alias for {print}. But that's not the case at all. 1 is not associated with the previous bracket. It is actually part of a second statement, which has no action, so it uses a default action of {print}. You can think of it like this instead.

    awk 'BEGIN{RS=".."} {gsub(OFS,"\t")}; 1!=0 {print}'
    

    Here's an example that I think demonstrates better the condition {action} format that awk uses:

    echo 'a b c' | awk '1 {print $1}; 2 {print $2}; 0 {print $3}'
    

    a and b are printed because 1 and 2 are nonzero and evaluate to true. c is not printed because 0 evaluates to false.

    0 讨论(0)
提交回复
热议问题