我的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美元。
答案 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表达式(通配符)匹配,请删除它们。否则,在脚本中过滤它们(不推荐)。