4

I was drafting a solution to a question earlier (this one actually), a simplified version:

$ echo {a..g} | tr ' ' '\n' |  # create some data
  awk  -v s=e '{               # search string as an argument
      for(i=1;i<=2;i++)        # keep 2 last records in a
          a[i]=a[i+1]          # this is the problematic part later
      a[3]=$1                  # hash the current record into a
  }
  $1==s {                      # once there is a match
      for(i=1;i<=3;i++)        # output from the hash
          print a[i]
  }'

Output:

c
d
e

Being me I had to try and make it a few bytes shorter (remove i++ from the for and a[i+1]-> a[++i]:

$ echo {a..g} | tr ' ' '\n' | 
gawk -v s=e '{
    # i=1; while(i<=2)  # fails with while also
    for(i=1;i<=2;)      # i++ moved
        a[i]=a[++i]     # ... here
    a[3]=$1
}
$1==s {
    for(i=1;i<=3;i++)
        print a[i]
}'

But the output failed on GNU awk:

    

e

After a while of wondering I switched to mawk and it worked. It also worked on Busybox awk but failed on awk-20121220. Any idea what causes the behaviour? Also, if you guys have a more descriptive idea for the title, feel free to change it.

4
  • 1
    You can simplify your script to BEGIN{ a[1]=5; a[2]=15; a[++i]+=a[++i]; print a[1], a[2] } to reproduce the same behaviour. Gawk evaluates the part after = the first, I don't know why. Commented Mar 23, 2019 at 21:43
  • 1
    @oguzismail Yeah, that pretty much explains it. Commented Mar 23, 2019 at 21:55
  • 1
    Lol, so how do I obfuscate this, for(i=2;i<=3;) a[i+=2]=a[i--] didn't work. :D:D After midnight is definitely not the time to think about this... Commented Mar 23, 2019 at 23:24
  • 1
    for(i=1;i<=2;) a[i++]=a[i+1], for(i=1;i<=2;) a[i-1]=a[++i], or just rewind the loop Commented Mar 23, 2019 at 23:46

1 Answer 1

4

From GNU Awk User's Guide:

It is up to the implementation as to which expression is evaluated first, the lefthand or the righthand. Consider this example:

i = 1
a[i += 2] = i + 1

The value of a[3] could be either two or four.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.