我正在尝试编写一个小脚本来计算日志文件中的条目,并且我正在递增一个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
-r阅读.cut,你可以坚持使用纯粹的bash解决方案.
read第二个var(_)以捕获其他"字段"[[ ]]超过[ ].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)
anu*_*ava 13
你得到final 0的while 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)
我在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)