脚本正在重新阅读论点

时间:2008-11-30 00:41:27

标签: linux bash shell scripting

当我为脚本提供参数时:hi [123] .txt它将完全符合我的要求。 但是如果我指定通配符(hi * .txt),它将重新读取一些文件。

我想知道如何修改这个脚本来解决这个愚蠢的问题:

#!/bin/sh

count="0"
total="0"
FILE="$1"  #FILE specification is now $1 Specification..

for FILE in $@
do
  #if the file is not readable then say so
     if [ ! -r $FILE ];
         then
         echo "File: $FILE not readable"
     exit 0
     fi


# Start processing readable files
  while read line
          do

             if [[ "$line" =~ ^Total ]];
                 then
                   tmp=$(echo $line | cut -d':' -f2)

                   total=$(expr $total + $tmp)

                   echo "$FILE (s) have a total of:$tmp "
                   count=$(expr $count + 1)

             fi

        done < $FILE
done
echo " Total is: $total"
echo " Number of files read is:$count"

4 个答案:

答案 0 :(得分:1)

我不知道它有什么问题,但我注意到了一点:

for FILE in $@更改为for FILE in "$@"。因为如果文件有嵌入空格,那么现在就是安全的。它会扩展为"$1" "$2" ...,而不是$1 $2 ...(并注意到你使用$ FILE的所有地方都要记得"")。

而其他人说,在进入循环之前,您不需要初始化FILE。它将自动设置为for循环中展开的位置参数的每个文件名。

但是,我会使用这样的awk脚本:

awk -F: '
/^Total/ { 
    total += $2
    # count++ not needed. see below
    print FILENAME "(s) have a total of: " $2
} 

END { 
    print "Total is: " total
    print "Number of files read is: " (ARGC-1) 
}' foo*.txt

请注意,当一个文件包含多个“^ Count”行时,如果依靠count告诉您读取的文件数,您确实会说您读取的文件数量超过实际读取的数量。

答案 1 :(得分:1)

这似乎是多余的:

FILE="$1"  #FILE specification is now $1 Specification..

for FILE in $@
  ...

初始分配会立即被覆盖。

总的来说,这似乎是一个更适合awk或perl等行处理语言的任务。

考虑一下这个awk脚本的内容:

BEGIN{
   TOTAL=0;
   COUNT=0;
   FS=':';
}
/^Total/{
   TOTAL += $2;
   COUNT++;
   printf("File '%s' has a total of %i",FILENAME,TOTAL);
}
END{
   printf("Total is %i",TOTAL);
   printf("Number of files read is%i",COUNT);
}

答案 2 :(得分:0)

这个解决方案怎么样:

for FILE in `/bin/ls $@`
do
. . .

这样可以有效地消除重复,因为/bin/ls hi1.txt hi1.txt hi1.txt只应显示hi1.txt一次。

虽然我不确定为什么它会重新读取文件。通配符扩展应该只包含每个文件一次。您是否有hi*.txt匹配的文件是指向hi[123].txt匹配的文件的链接?

答案 3 :(得分:0)

出错时,退出非零状态。同样出错时,将错误报告给标准错误,而不是标准输出 - 尽管这对您来说可能有点先进。

echo "$0: file $FILE not readable" 1>&2

1在理论上是不必要的(虽然我记得在Windows上有一个shell实现的问题,如果它被省略)。在错误消息的开头回应脚本名称“$0”也是一个好主意 - 当您的脚本在其他上下文中使用时,它会使错误跟踪更容易。

我相信Perl one-liner能胜任你所追求的工作。

perl -na -F: -e '$sum += $F[1] if m/^Total:/; END { print $sum; }' "$@"

我知道您正在学习shell编程,但shell编程的一个重要事项是知道要使用哪些程序。