计算循环中的计数失败

问题描述:

这是我的简化代码。 ls被简化为找到命令。 wc被简化为另一个命令。计算循环中的计数失败

n=0 
ls *.cpp | while read filename ; do 
    c=`wc -l $filename | awk '{print $1}'}` 
    n=`expr $n + $c` 
done 
echo "$n" #always be 0 

在前面的代码失败,以下成功

n=0 
ls *.cpp > /tmp/list 
while read filename ; do 
    c=`wc -l $filename | awk '{print $1}'}` 
    n=`expr $n + $c` 
done < /tmp/list 
echo "$n" 

如何使用第一种形式,并得到正确的答案? 或者,如何使用第二种形式,但没有另一个/ tmp /列表文件?

也许我的问题是如何通过其自动生成

在管,every process except the first one is in a subshell,因此$c$n的值将丢失。如果你想保持计数,你应该首先把while循环:

while read ...; do 
    c=... 
    n=... 
done < <(find . -maxdepth 1 -name '*.cpp') 
echo "$n" 

但还有一个更好的方法:

wc -l *.cpp | tail -1 | awk '{ print $1 }' 
+0

+1。如果我们打高尔夫,这个过程就会少一些:'wc -l 2012-03-07 11:13:47

+0

这不是打高尔夫球,而是'cat * .cpp | wc -l';) – l0b0 2012-03-07 12:59:27

我可能会使用下面的一行壳层之间的变量:

wc -l *.cpp | tail -n1 | awk '{print $1}' 

但是,如果你喜欢解决您的原始脚本,你可以使用一个for循环,而不是一个while循环如下:

#!/bin/bash 
n=0 
for filename in *.cpp; do 
    c=`wc -l $filename | awk '{print $1}'` 
    n=`expr $n + $c` 
done 
echo "$n" 
+0

的代码被用于解释语法。我的原始脚本的目的不用于计算字数。 – 2012-03-07 08:57:31

+0

@DanielYCLin使用'ls'的输出是一种不好的做法,例如,如果您的文件名之间存在空格(或者您在'IFS'中使用的任何分隔符),则输出失败。迭代文件的最好方法是使用上面例子中的for循环。 – jcollado 2012-03-07 09:05:11