增加Bash循环内的变量

mae*_*sto 41 bash shell loops

我正在尝试编写一个小脚本来计算日志文件中的条目,并且我正在递增一个USCOUNTER我想在循环完成后尝试使用的变量().

但那时USCOUNTER看起来是0而不是实际价值.知道我做错了什么吗?谢谢!

FILE=$1

tail -n10 mylog > $FILE

USCOUNTER=0

cat $FILE | while read line; do
  country=$(echo "$line" | cut -d' ' -f1)
  if [ "US" = "$country" ]; then
        USCOUNTER=`expr $USCOUNTER + 1`
        echo "US counter $USCOUNTER"
  fi
done
echo "final $USCOUNTER"
Run Code Online (Sandbox Code Playgroud)

它输出:

US counter 1
US counter 2
US counter 3
..
final 0
Run Code Online (Sandbox Code Playgroud)

fed*_*qui 43

您正在USCOUNTER子shell 中使用,这就是变量未在主shell中显示的原因.

而不是cat FILE | while ...,只做一个while ... done < $FILE.这样,您可以避免我在管道中的循环中设置变量的常见问题.它们为什么在循环结束后消失?或者,为什么我不能管道数据读取?:

while read country _; do
  if [ "US" = "$country" ]; then
        USCOUNTER=$(expr $USCOUNTER + 1)
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"
Run Code Online (Sandbox Code Playgroud)

注意我也用$()替换了``表达式.

我也换while read line; do country=$(echo "$line" | cut -d' ' -f1)while read country _.这使您可以说while read var1 var2 ... varN在那里var1包含在该行的第一个字,$var2等等,直到$varN包含剩余的内容.


Ale*_*-A. 25

while read -r country _; do
  if [[ $country = 'US' ]]; then
    ((USCOUNTER++))
    echo "US counter $USCOUNTER"
  fi
done < "$FILE"
Run Code Online (Sandbox Code Playgroud)


gee*_*pot 14

极简主义

counter=0
((counter++))
echo $counter
Run Code Online (Sandbox Code Playgroud)

  • 在您的示例中,想要的 while 循环在哪里? (3认同)
  • 一些解释将不胜感激 (2认同)

anu*_*ava 13

你得到final 0while loop是因为你正在子(shell)进程中执行,并且那里所做的任何更改都没有反映在当前(父)shell中.

正确的脚本:

while read -r country _; do
  if [ "US" = "$country" ]; then
        ((USCOUNTER++))
        echo "US counter $USCOUNTER"
  fi
done < "$FILE"
Run Code Online (Sandbox Code Playgroud)


job*_*wat 6

我在while循环中遇到了相同的$ count变量.

@ fedorqui的答案(以及其他几个)是对实际问题的准确答案:子shell确实是问题所在.

但它引出了另一个问题:我没有管道文​​件内容...但是输出了一系列的管道和greps ......

我的错误示​​例代码:

count=0
cat /etc/hosts | head | while read line; do
  ((count++))
  echo $count $line
done
echo $count
Run Code Online (Sandbox Code Playgroud)

感谢这个线程的帮助和进程替换:

count=0
while IFS= read -r line; do
  ((count++))
  echo "$count $line"
done < <(cat /etc/hosts | head)
echo "$count"
Run Code Online (Sandbox Code Playgroud)