Counter increment in Bash loop not working

前端 未结 13 2247
庸人自扰
庸人自扰 2020-12-02 05:31

I have the following simple script where I am running a loop and want to maintain a COUNTER. I am unable to figure out why the counter is not updating. Is it du

相关标签:
13条回答
  • 2020-12-02 06:09
    count=0   
    base=1
    (( count += base ))
    
    0 讨论(0)
  • 2020-12-02 06:10

    Try to use

    COUNTER=$((COUNTER+1))
    

    instead of

    COUNTER=$((COUNTER))
    
    0 讨论(0)
  • 2020-12-02 06:10

    I think this single awk call is equivalent to your grep|grep|awk|awk pipeline: please test it. Your last awk command appears to change nothing at all.

    The problem with COUNTER is that the while loop is running in a subshell, so any changes to the variable vanish when the subshell exits. You need to access the value of COUNTER in that same subshell. Or take @DennisWilliamson's advice, use a process substitution, and avoid the subshell altogether.

    awk '
      /GET \/log_/ && /upstream timed out/ {
        split($0, a, ", ")
        split(a[2] FS a[4] FS $0, b)
        print "http://example.com" b[5] "&ip=" b[2] "&date=" b[7] "&time=" b[8] "&end=1"
      }
    ' | {
        while read WFY_URL
        do
            echo $WFY_URL #Some more action
            (( COUNTER++ ))
        done
        echo $COUNTER
    }
    
    0 讨论(0)
  • 2020-12-02 06:10

    minimalist

    counter=0
    ((counter++))
    echo $counter
    
    0 讨论(0)
  • 2020-12-02 06:10

    This is all you need to do:

    $((COUNTER++))
    

    Here's an excerpt from Learning the bash Shell, 3rd Edition, pp. 147, 148:

    bash arithmetic expressions are equivalent to their counterparts in the Java and C languages.[9] Precedence and associativity are the same as in C. Table 6-2 shows the arithmetic operators that are supported. Although some of these are (or contain) special characters, there is no need to backslash-escape them, because they are within the $((...)) syntax.

    ..........................

    The ++ and - operators are useful when you want to increment or decrement a value by one.[11] They work the same as in Java and C, e.g., value++ increments value by 1. This is called post-increment; there is also a pre-increment: ++value. The difference becomes evident with an example:

    $ i=0
    $ echo $i
    0
    $ echo $((i++))
    0
    $ echo $i
    1
    $ echo $((++i))
    2
    $ echo $i
    2
    

    See http://www.safaribooksonline.com/a/learning-the-bash/7572399/

    0 讨论(0)
  • 2020-12-02 06:14

    Instead of using a temporary file, you can avoid creating a subshell around the while loop by using process substitution.

    while ...
    do
       ...
    done < <(grep ...)
    

    By the way, you should be able to transform all that grep, grep, awk, awk, awk into a single awk.

    Starting with Bash 4.2, there is a lastpipe option that

    runs the last command of a pipeline in the current shell context. The lastpipe option has no effect if job control is enabled.

    bash -c 'echo foo | while read -r s; do c=3; done; echo "$c"'
    
    bash -c 'shopt -s lastpipe; echo foo | while read -r s; do c=3; done; echo "$c"'
    3
    
    0 讨论(0)
提交回复
热议问题