我正在尝试编写一个小脚本来计算日志文件中的条目,并且我正在递增一个变量(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
答案 0 :(得分:42)
您在子shell中使用USCOUNTER
,这就是变量未在主shell中显示的原因。
而不是cat FILE | while ...
,而只需while ... done < $FILE
。这样,您可以避免I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?:
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 country _
。这样您就可以说while read var1 var2 ... varN
其中var1
包含行中的第一个单词$var2
,依此类推,直到$varN
包含剩余内容。
答案 1 :(得分:22)
-r
with read。cut
,您可以坚持使用纯粹的bash解决方案。
read
第二个var(_
)以捕获其他“字段”[[ ]]
over [ ]
。while read -r country _; do
if [[ $country = 'US' ]]; then
((USCOUNTER++))
echo "US counter $USCOUNTER"
fi
done < "$FILE"
答案 2 :(得分:12)
您将获得final 0
,因为您的while loop
正在子(shell)进程中执行,并且所做的任何更改都不会反映在当前(父)shell中。
正确的脚本:
while read -r country _; do
if [ "US" = "$country" ]; then
((USCOUNTER++))
echo "US counter $USCOUNTER"
fi
done < "$FILE"
答案 3 :(得分:12)
极简
counter=0
((counter++))
echo $counter
答案 4 :(得分:6)
我在while循环中遇到了丢失问题的同一$ count变量。
@fedorqui's answer(以及其他几个)是对实际问题的准确答案:子shell确实是问题。
但它引出了另一个问题:我没有管道文件内容......但是输出了一系列管道和输出。里grep ...
我的错误示例代码:
count=0
cat /etc/hosts | head | while read line; do
((count++))
echo $count $line
done
echo $count
和我的修复感谢这个帖子和process substitution:
的帮助count=0
while IFS= read -r line; do
((count++))
echo "$count $line"
done < <(cat /etc/hosts | head)
echo "$count"
答案 5 :(得分:2)
USCOUNTER=$(grep -c "^US " "$FILE")
答案 6 :(得分:0)
增量变量可以这样做:
_my_counter=$[$_my_counter + 1]
使用grep
计算列中模式的出现次数 grep -cE "^([^ ]* ){2}US"
-c
计数
([^ ]* )
检测上校
{2}
结肠号
US
你的模式
答案 7 :(得分:0)
使用以下1行命令在linux中使用短语特异性更改许多文件名:
find -type f -name '*.jpg' | rename 's/holiday/honeymoon/'
对于扩展名为&#34; .jpg&#34;的所有文件,如果它们包含字符串&#34;假日&#34;,请将其替换为#34;蜜月&#34;。例如,此命令将重命名文件&#34; ourholiday001.jpg&#34; to&#34; ourhoneymoon001.jpg&#34;。
此示例还说明了如何使用find命令发送扩展名为.jpg(-name&#39; *。jpg&#39;)的文件列表(-type f),以通过管道重命名(| )。然后重命名从标准输入中读取其文件列表。