繁体   English   中英

增加Bash循环内的变量

[英]Incrementing a variable inside a Bash loop

我正在尝试编写一个USCOUNTER计算日志文件中的条目,我正在递增一个变量( 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"

它输出:

US counter 1
US counter 2
US counter 3
..
final 0

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

而不是cat FILE | while ... 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"

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

我也在while read line; do country=$(echo "$line" | cut -d' ' -f1)更换了while read line; do country=$(echo "$line" | cut -d' ' -f1) while read line; do country=$(echo "$line" | cut -d' ' -f1) with while read country _ 这允许您while read var1 var2 ... varN说明var1包含行中的第一个单词$var2 ,依此类推,直到$varN包含剩余内容。

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

极简主义

counter=0
((counter++))
echo $counter

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

正确的脚本:

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

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

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

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

我的错误示​​例代码:

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

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

count=0
while IFS= read -r line; do
  ((count++))
  echo "$count $line"
done < <(cat /etc/hosts | head)
echo "$count"
USCOUNTER=$(grep -c "^US " "$FILE")

增量变量可以这样做:

  _my_counter=$[$_my_counter + 1]

计算列中模式的出现次数可以使用grep来完成

 grep -cE "^([^ ]* ){2}US"

-c计数

([^ ]* )检测结肠

{2}结肠数

US你的模式

使用以下1行命令在linux中使用短语特征更改许多文件名:

find -type f -name '*.jpg' | rename 's/holiday/honeymoon/'

对于扩展名为“.jpg”的所有文件,如果它们包含字符串“holiday”,请将其替换为“honeymoon”。 例如,此命令会将文件“ourholiday001.jpg”重命名为“ourhoneymoon001.jpg”。

此示例还说明了如何使用find命令发送扩展名为.jpg(-name'* .jpg')的文件列表(-type f),以通过管道(|)重命名。 然后重命名从标准输入读取其文件列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM