2

I have the following section of code:

 if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerECHLane") {
                $11 ~ /ms/ ( SUM10 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min10 = (min < $11 ? min : $11)
                max10 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                }

and I was wondering what !i++ does as I know that i++ increments the variable after it has been used and that ++i increments the variable before it is used.

I have tried Google but it is only showing me the differences between i++ and ++i

Thanks in advance.

As Promised please see the following for the full script:

#!/usr/bin/gawk -f

BEGIN {
min01 = 0
min02 = 0
min03 = 0
min04 = 0
min05 = 0
min06 = 0
min07 = 0 
min08 = 0 
min09 = 0
min10 = 0
max01 = 0 
max02 = 0 
max03 = 0
max04 = 0
max05 = 0
max06 = 0
max07 = 0
max08 = 0
max09 = 0 
max10 = 0
SUM01 = 0
SUM02 = 0
SUM03 = 0 
SUM04 = 0 
SUM05 = 0 
SUM06 = 0 
SUM07 = 0 
SUM08 = 0 
SUM09 = 0
SUM10 = 0
} #End of BEGIN
{ #Start of MID
    if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerPackingInfeedHanging") {
        $11 ~ /ms/ ( SUM01 += $11)
        if ($11 ~ /ms/) {
        !i++ (min = $11)
        !i++ (max = $11)
        {
        for (j= NR; j<= FNR; ++j) {
            min01 = (min < $11 ? min : $11)
            max01 = (max > $11 ? max : $11)
                      } #End of for
                }} #End of for wrapper
        } else
    if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerPackingAreaNOK") {
        $11 ~ /ms/ ( SUM02 += $11)
                !i++ (min = $11)
        !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min02 = (min < $11 ? min : $11)
                max02 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
        } else
     if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerPackingAreaMPANOK") {
                $11 ~ /ms/ ( SUM03 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min03 = (min < $11 ? min : $11)
                max03 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
     if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerPackingOrderBufferHanging") {
                $11 ~ /ms/ ( SUM04 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min04 = (min < $11 ? min : $11)
                max04 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerTUNotification") {
                $11 ~ /ms/ ( SUM05 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min05 = (min < $11 ? min : $11)
                max05 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerLaneStatusLaneLocker") {
                $11 ~ /ms/ ( SUM06 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min06 = (min < $11 ? min : $11)
                max06 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerPackingHangingBufferLane") {
                $11 ~ /ms/ ( SUM07 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min07 = (min < $11 ? min : $11)
                max07 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerLaneStatusHangingMPA") {
                $11 ~ /ms/ ( SUM08 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min08 = (min < $11 ? min : $11)
                max08 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerMPAHangingBufferLane") {
                $11 ~ /ms/ ( SUM09 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min09 = (min < $11 ? min : $11)
                max09 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                } else
         if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerECHLane") {
                $11 ~ /ms/ ( SUM10 += $11)
                !i++ (min = $11)
                !i++ (max = $11)
                {
                for (j= NR; j<= FNR; ++j) {
                min10 = (min < $11 ? min : $11)
                max10 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                }

    MSG_TYPE[substr($12,match($12,":")+1,match($12,")")-15)]++;
} #End of MID
END {
        for (b in MSG_TYPE) 
        if (b == "TelegramHandlerPackingInfeedHanging") {
            print b
                        print "MIN: "min01
                        print "MAX: "max01
                        print "AVG: "SUM01/FNR"ms"
                } else
        if (b == "TelegramHandlerPackingAreaNOK") {
            print b
                        print "MIN: "min02
                        print "MAX: "max02
                        print "AVG: "SUM02/FNR"ms"
                } else
                if (b == "TelegramHandlerPackingAreaMPANOK") {
            print b
                        print "MIN: "min03
                        print "MAX: "max03
                        print "AVG: "SUM03/FNR"ms"
                } else
                if (b == "TelegramHandlerPackingOrderBufferHanging") {
            print b
                        print "MIN: "min04
                        print "MAX: "max04
                        print "AVG: "SUM04/FNR"ms"
                } else
                if (b == "TelegramHandlerTUNotification") {
            print b
                        print "MIN: "min05
                        print "MAX: "max05
                        print "AVG: "SUM05/FNR"ms"
                } else
                if (b == "TelegramHandlerLaneStatusLaneLocker") {
            print b
                        print "MIN: "min06
                        print "MAX: "max06
                        print "AVG: "SUM06/FNR"ms"
                } else
                if (b == "TelegramHandlerPackingHangingBufferLane") {
            print b
                        print "MIN: "min07
                        print "MAX: "max07
                        print "AVG: "SUM07/FNR"ms"
                } else
                if (b == "TelegramHandlerLaneStatusHangingMPA") {
            print b
                        print "MIN: "min08
                        print "MAX: "max08
                        print "AVG: "SUM08/FNR"ms"
                } else
                if (b == "TelegramHandlerMPAHangingBufferLane") {
            print b
                        print "MIN: "min09
                        print "MAX: "max09
                        print "AVG: "SUM09/FNR"ms"
                } else
                if (b == "TelegramHandlerECHLane") {
            print b
                        print "MIN: "min10
                        print "MAX: "max10
                        print "AVG: "SUM10/FNR"ms"
}
} #End of END

A example of the output that is getting returned:

TelegramHandlerPackingInfeedHanging
MIN: 19.7ms
MAX: 19.7ms
AVG: 3.05067ms
TelegramHandlerPackingAreaNOK
MIN: 25.3ms
MAX: 25.3ms
AVG: 0.00706937ms
TelegramHandlerPackingAreaMPANOK
MIN: 22.3ms
MAX: 22.3ms
AVG: 4.26834e-05ms
TelegramHandlerPackingOrderBufferHanging
MIN: 12.0ms
MAX: 12.0ms
AVG: 1.60741ms
TelegramHandlerTUNotification
MIN: 8.7ms
MAX: 8.7ms
AVG: 4.00978ms
TelegramHandlerLaneStatusLaneLocker
MIN: 15.0ms
MAX: 15.0ms
AVG: 0.0527127ms
TelegramHandlerPackingHangingBufferLane
MIN: 23.9ms
MAX: 23.9ms
AVG: 13.3463ms
TelegramHandlerLaneStatusHangingMPA
MIN: 312.5ms
MAX: 312.5ms
AVG: 0.0126846ms
TelegramHandlerMPAHangingBufferLane
MIN: 57.0ms
MAX: 57.0ms
AVG: 0.135032ms
TelegramHandlerECHLane
MIN: 7.0ms
MAX: 7.0ms
AVG: 2.81495ms

This is partly doing what I wanted it to. Return the message,substr($12,match($12,":")+1,match($12,")")-15) along with the min time took to process, max time took to process and the AVG time to process. Although the min and max values are the same so I think that the values are getting overwritten rather than being worked out individually and them saved to the variable min01 - min10, max01 - max10, SUM01 - SUM10.

glly
  • 107
  • 7
  • A. you can confirm that this code works and provides reliable results? Or could it be orphan code that never gets executed? B. It would really help to see how the value of `i` is being used in larger context. Are the 2 lines `!i++` the only place? C. Other odd syntax makes me think the original writer wasn't a native `awk` speaker, but it partly depends on when a person starts using `awk`. All this is to say, "Just looking for clues". I guess you could add debugging to show value of `i` (before it is set) !(empty) VS !(value) but I don't see how it could be used as a conditional. Good luck! – shellter Jun 16 '16 at 04:06
  • AFAICT, GNU `awk` accepts it but BSD (Mac OS X) `awk` does not. It looks as though it was written as if `!i++ (min = $11)` was equivalent to `if (!i++) min = $11`. That would mean that if `i` was zero, then `min` would be set to the value in `$11`. The `!i++ (max = $11)` line puzzles me; the preceding line increments `i` so this will never be true. The wrapped `for` loop is esoteric too; it executes its body once per line of input in the first file, and not thereafter. The code is excruciating — it should be rewritten to make it clear what it is doing. – Jonathan Leffler Jun 16 '16 at 04:08
  • @JonathanLeffler: BSD awk is complaining about the unmatched `)` in the regular expression `")"`. If you change it to `"[)]"`, the error should go away. It does indeed look like they expect to be able to use the statement `guard (action)` in an analogy with `guard {action}`, but of course awk (both gawk and BSD awk) interpret `!i++ (min = $11)` as the string concatenation of 0 or 1 with `$11`, while setting `min` to `$11` as a side effect; awk does not complain about useless evaluation. – rici Jun 16 '16 at 04:16
  • I can defiantly say that I am not a `awk` speaker. I am trying to write this on a 12 hour shift with next to no sleep. I will update the original question with the full script in a minute + provide the out put that I am getting. I can see that it is doing what I "wanted" it to do but it just seemed a little odd. (pulled from Google) – glly Jun 16 '16 at 04:20
  • @rici: sounds at least semi-plausible. It remains excruciatingly awful `awk`. I haven't worked out what the `if` condition matches either — I'm not sure whether I'm worried about it. – Jonathan Leffler Jun 16 '16 at 04:24
  • I am worried I have spent a full 12 hour shift on this and I am not 100% sure what it is doing anymore. :( – glly Jun 16 '16 at 04:32
  • @jonathan: Yeah, that `if` conditional is painfully obfuscated. I believe that it succeeds if field 12 contains `:TelegramHandlerECHLane` and also has a `)` at exactly character index 37. – rici Jun 16 '16 at 04:34
  • 2
    @glennLynam: If you wrote that code, then I'd say you would have been much better off using the first ten hours of your shift to read the [Gawk book](https://www.gnu.org/software/gawk/manual/) or some other [awk reference](https://en.wikipedia.org/wiki/AWK#Books), after which you would probably have been able to write your program in the remaining two hours. – rici Jun 16 '16 at 04:38
  • @rici:I have been reading it as I go just to clarify on some of the functions, but I don't really learn by reading I learn by doing and trying things out. Sorry for the bad code, it just needs to function (for us) it can be tided up at a later date by one of us who actually knows `awk` – glly Jun 16 '16 at 04:42
  • When people ask to see a complete script, they aren't asking to see the 100+ line script you have lying around in your file system. They're asking you to **create the smallest possible complete script** that can reproduce the problem you are having and post **that script**. You should assume that we are all busy and so the more effort you put into creating a [mcve] the better chance someone will read the question and help you. See [ask].If you're going to be using awk, you must get SOME instruction to start you on the right path - read Effective Awk Programming, 4th Edition, by Arnold Robbins. – Ed Morton Jun 16 '16 at 12:42

3 Answers3

2

Is that real awk code? Because it sure doesn't look like it...

If you were looking at something like:

!i++      { min = $11 }
$11 < min { min = $11 }

(at the top level), then it would just be obfuscation; it would mean the same as:

{ if (NR==1 || $11 < min) min = $11; }

or equivalently

NR == 1 || $11 < min  { min = $11; }

In other words, set min to the value of the 11th field if you're on the first line, or if the 11th field is smaller than the current value of min. In !i++, i++ increments i but returns the original unincremented value as the value which is passed to !, which means that the whole expression:

  • unconditionally increments i
  • is true if i was 0 or uninitialized before the increment
rici
  • 234,347
  • 28
  • 237
  • 341
2

Whoever wrote it was trying to init their min and max variables to the first values seen and were confused by awk's general <condition> { <action> } syntax not being applicable inside an action block.

Remember: i starts off with value zero so then !i is 1 and i++ is a post-increment so !i++ is also 1 the first time it's encountered but second time round i is 1 and so !i++ is zero and third time i is 2 and !i++ is still zero and so on...

This is what they meant to write:

 if (substr($12,match($12,":")+1,match($12,")")-15) == "TelegramHandlerECHLane") {
                if ($11 ~ /ms/) {SUM10 += $11}
                if (!i++) {min = $11; max = $11}
                {
                for (j= NR; j<= FNR; ++j) {
                min10 = (min < $11 ? min : $11)
                max10 = (max > $11 ? max : $11)
                                          } #End of for
                                } #End of for wrapper
                }

but it still doesn't really make sense.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
1

This code intends to initialize min and max values to the first value encountered.

Author thought that !i++ (min = $11) was the equivalent of

if (!i) {
    i++
    min=$11
}

It would have been true with !i++&&(min=$11)

Adam
  • 17,838
  • 32
  • 54