如何让我的bash脚本工作?

时间:2008-11-29 00:15:06

标签: 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 $line | cut -d':' -f2)
            count=$(expr $count + 1)
            total=$(expr $total + $tmp)
        fi     
    done < $FILE
done
echo "The Total Is: $total"
echo "$FILE"

是否有其他方法可以修改此脚本,以便将参数读入$1而不是$FILE?我尝试过使用while循环:

while [ $1 != "" ]
  do ....
done

当我实现代码重复时。有没有办法解决这个问题?

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


我拥有的很好,但可以改进。我很欣赏你的awk建议,但它目前超出了我作为unix程序员的水平。

Strager:我的文本编辑器生成的文件自动包含任何内容..它是0字节..但是,我继续删除它们只是为了确定。但是我的剧本实际上并没有两次阅读。我认为当它真的不应该再循环。我试图用退出命令使这个动作沉默。但是没有成功。

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

    # Next argument
    shift
done

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

我如何编码它以便在指定hi * .txt时读取我的文件(只需一次)? 我真的认为这是因为没有1美元。

3 个答案:

答案 0 :(得分:2)

看起来您正在尝试将所提供文件中标有“总计:”的行中的总计相加。说出你想要做的事情以及你是如何做到这一点总是一个好主意(见How to Ask Questions the Smart Way)。

如果是这样,那么你所做的事情就像我看到的那样复杂。出了什么问题:

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完成:

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

HTH!

答案 1 :(得分: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

答案 2 :(得分:1)

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

    # Next argument
    shift
done

关于代字号文件的问题......这些是由文本编辑器创建的临时文件。如果您不希望它们与glob表达式(通配符)匹配,请删除它们。否则,在脚本中过滤它们(不推荐)。