我想创建一个从 1 运行到变量中存储的数字的 for 循环。但它会产生这个错误:
语法错误:for 循环变量不正确
这是我的脚本:
#!/bin/bash
count_lines ()
{
local f=$1
l=`wc -l $f | sed 's/^\([0-9]*\).*$/\1/'`
}
echo "$0 counts the lines of code"
l=0
while [ "$*" != "" ]
do
count_lines $1
echo "$1: $l"
shift
done
for(( i= 0 ; i <= ${l} ; i++))
do
title=$(grep -oPm1 "(?<=<title>)[^<]+" <<< "$0")
echo "$title"
done
答案1
确保脚本可执行,只需键入命令(包括其路径)即可运行脚本。例如,如果脚本被调用foo
并且位于当前目录中,则运行
./foo
鉴于错误消息,您正在执行类似的操作sh foo
。这将在 下运行脚本sh
,而不是bash
.sh
您的机器上有一个不同的 shell,可能是 dash,它不支持您使用的 for 循环语法。通过运行./foo
,您的脚本将由第一行中提到的 shell 执行,即 bash。
你的脚本有几个地方很奇怪:
- 始终在变量替换两边加上双引号:
"$1"
,"$f"
, ETC。 该
while [ "$*" != "" ] …
循环是一种迭代脚本参数的非常迂回的方式。简单、惯用的方法是for x; do count_lines "$x" done
或者
for x in "$@"; do count_lines "$x" done
- 我不确定你想做什么
title=$(grep -oPm1 "(?<=<title>)[^<]+" <<< "$0")
;"$0"
是脚本的路径,因此您(?<=<title>)[^<]+
在脚本的路径中搜索正则表达式,这没有多大意义。
答案2
我认为主要问题是不测试文件是否确实存在并获得l
对循环无效的计数for
。
看看这个(经过非常修改的)类似的脚本,可以给你一些想法:
#!/bin/bash
count_lines() {
if [[ -r $1 ]]; then # if the file exist.
l="$(wc -l "$1")" # count the number of lines.
l="${l%%[^0-9]*}" # remove anything that is not a digit from the end.
else
l=0
fi
}
echo "$0 counts the lines of code"
for file; do # while there is an argument.
count_lines "$file" # execute the function above
echo "$file: $l" # print the number of lines.
done
echo "$(grep -oPm1 "(?<=<title>)[^<]+" "$0")"
我不明白为什么你尝试运行l
命令(grep)来查找title
文件内部。一次就够了。
此外,grep 命令正在读取脚本(而不是外部文件)。
正如吉尔斯所说:严重纠正你的代码,发布一个新问题。