如何使bash脚本正常工作?

如何使bash脚本正常工作?,bash,unix,shell,Bash,Unix,Shell,我的bash脚本无法按我希望的方式工作: #!/bin/bash total="0" count="0" #FILE="$1" This is the easier way for FILE in $* do # Start processing all processable files while read line do if [[ "$line" =~ ^Total ]]; then tmp=$(echo

我的bash脚本无法按我希望的方式工作:

#!/bin/bash

total="0"
count="0"
#FILE="$1" This is the easier way
for FILE in $*
do
    # Start processing all processable files
    while read line
    do
        if [[ "$line" =~ ^Total ]];
        then
            tmp=$(echo $line | cut -d':' -f2)
            count=$(expr $count + 1)
            total=$(expr $total + $tmp)
        fi     
    done < $FILE
done
echo "The Total Is: $total"
echo "$FILE"
而且,当我实现时,代码会自动重复。有没有办法解决这个问题

我遇到的另一个问题是,当我有多个文件
hi*.txt
时,它会给我重复的文件。为什么?我有像
hi1.txt
hi1.txt~
这样的文件,但是tilde文件是0字节的,所以我的脚本应该找不到任何东西


我所拥有的一切都很好,但还可以改进。我很感谢您的awk建议,但它目前超出了我作为unix程序员的水平

斯特拉格:我的文本编辑器自动生成的文件不包含任何内容。它有0个字节。但是是的,我继续删除了它们只是为了确定。但不,我的剧本实际上是把所有的东西都读了两遍。我想它真的不应该再循环了。我试着用退出命令来阻止这个动作,但没有成功

while [ "$1" != "" ]; do
    # Code here

    # Next argument
    shift
done
这段代码非常好,但我同时指定了所有可能的命令。示例:hi[145].txt 如果提供,将同时读取所有三个文件。 假设用户输入hi*.txt; 然后我将所有hi文件读取两次,然后再次添加

如何对其进行编码,使其根据hi*.txt的规范读取我的文件(仅一次)?
我真的认为这是因为没有$1。

如果定义一个函数,它将接收参数$1。为什么1美元对你来说比$FILE更有价值呢

#!/bin/sh

process() {
    echo "doing something with $1"
}

for i in "$@" # Note use of "$@" to not break on filenames with whitespace
do
    process "$i"
done

关于tilde文件的问题。。。这些是由文本编辑器创建的临时文件。如果不希望全局表达式(通配符)匹配它们,请删除它们。否则,请在脚本中筛选它们(不推荐)。

看起来您正试图从提供的文件中标记为“总计”的行中添加总计。陈述你想做的事情以及你想怎么做总是一个好主意(参见)

如果是这样的话,那么你正在以我所能看到的最复杂的方式进行。问题是:

grep '^Total:' "$@" |
cut -d: -f2 |
awk '{sum += $1}
     END { print sum }'
这不会打印出“总数”等;现在还不清楚为什么要在版本末尾回显$FILE

您可以使用Perl或任何其他合适的程序来代替
awk
;您可以用Perl或Python完成整个工作-实际上,
cut
工作可以通过
awk
完成:

grep "^Total:" "$@" |
awk -F: '{sum += $2}
         END { print sum }'
awk -F: '$1 ~ /^Total/ { sum += $2 }
         END { print sum }' "$@"
更进一步说,整个工作可以通过
awk
完成:

grep "^Total:" "$@" |
awk -F: '{sum += $2}
         END { print sum }'
awk -F: '$1 ~ /^Total/ { sum += $2 }
         END { print sum }' "$@"
Perl中的代码不会太难,结果可能会更快:

perl -na -F: -e '$sum += $F[1] if m/^Total:/; END { print $sum; }' "$@"
当在shell脚本中提供的文件名参数上进行迭代时,应使用“
”$@“
”代替“
$*
”,因为后者不会在文件名中保留空格

你关于“
$1
”的评论让我感到困惑。在每次迭代中,您可能会要求读取名称在
$1
中的文件;这是通过以下方式实现的:

while [ $# -gt 0 ]
do
     ...process $1...
     shift
done

请把你的代码格式化一点。全部选中并单击小代码按钮,或者至少确保缩进四个空格。