我的任务是编写一个分析代码的脚本,并附加与#Loop
n或#Selection n
相对应的正确陈述的评论。
echo "enter full file name: "
read file
getArray(){
arr=()
while IFS= read -r line
do
arr+=("$line")
done < "$1"
}
getArray $file
echo "What file looks like before editing"
printf "%s\n" "${arr[@]}" #Test function to see if array works (it does)
#Declare variables
x=1
y=1
#Start main loop
for (( i=0; i<${#arr[@]}; i++ ));
do
if [[ "${arr[$i]}" == "while" ]] || [[ "${arr[$i]}" == "until" ]]
then sed -i 's/$/ #Loop'$x'/' $file && let "x++"
continue
elif [[ "${arr[$i]}" == "for" ]]
then sed -i 's/$/ #Loop'$x'/' $file && let "x++"
continue
elif [[ "${arr[$i]}" == "break" ]] || [[ "${arr[$i]}" == "done" ]]
then sed -i 's/$/ #Loop'$x'/' $file && let "x--"
continue
elif [[ "${arr[$i]}" == "if" ]] || [[ "${arr[$i]}" == "case" ]]
then sed -i 's/$/ #Selection'$y'/' $file && let "y++"
continue
elif [[ "${arr[$i]}" == "fi" ]] || [[ "${arr[$i]}" == "esac" ]]
then sed -i 's/$/ #Selection'$y'/' $file && let "y--"
continue
else
continue
fi
done < $file
显然我是bash的新手,我的循环逻辑/语言用法可能有点不稳定。有人可以帮忙吗?现在输出使得我似乎不止一次遍历数组,并且Sed每行附加额外的文本。
如果不清楚:每个数组元素都是一串字符串;如果数组元素包含while || for || until
,那么它会添加#loop n
,并且每个对应的break
或done
都会添加相同的#loop n
。同样适用于if
和case
以及fi
esac
,但会添加#selection n
。
示例输入:
Before
Final=$(date -d "2016-12-15 14:00" "+%j")
while true ; do
Today=$(date "+%j")
Days=$((Final - Today))
if (( Days >= 14 )) ; then
echo party
elif (( Days >= 2 )) ; then
echo study
elif (( Days == 1 )) ; then
for Count in 1 2 3
do
echo panic
done
else
break
fi
sleep 8h
done
预期产出:
After
Final=$(date -d "2016-12-15 14:00" "+%j")
while true ; do # loop 1
Today=$(date "+%j")
Days=$((Final - Today))
if (( Days >= 14 )) ; then # selection 1
echo party
elif (( Days >= 2 )) ; then
echo study
elif (( Days == 1 )) ; then
for Count in 1 2 3 # loop 2
do
echo panic
done # loop 2
else
break
fi # selection 1
sleep 8h
done # loop 1
答案 0 :(得分:0)
现在输出使得我似乎不止一次遍历数组,并且Sed每行附加额外的文本。
这是因为附加到一行的注释会附加到文件的每一行,因为没有为脚本中的sed
替换命令指定行号。肯定有更有效的解决方案,但预先填写相应的行号就足够了。
虽然你的脚本非常接近工作,但还有两个问题需要解决。一个是用于测试关键字的==
表达式只有在整行包含除关键字以外的任何内容时才匹配(甚至不包括前导空格);为了允许缩进,=~
具有适当的正则表达式是有用的。另一个问题是嵌套深度的计数(包括break
的简单但特殊的情况,其中深度保持不变);如果我们从深度0
开始,这似乎更容易。因此,您的主循环可以是:
x=0
y=0
#Start main loop
for (( i=0; i<${#arr[@]}; i++ ))
do let l=1+i # line numbers start at 1
if [[ "${arr[$i]}" =~ ^[$IFS]*(while|until|for) ]]
then sed -i $l"s/$/ #Loop$((++x))/" $file
elif [[ "${arr[$i]}" =~ ^[$IFS]*break ]]
then sed -i $l"s/$/ #Loop$x/" $file # no x-- here!
elif [[ "${arr[$i]}" =~ ^[$IFS]*done ]]
then sed -i $l"s/$/ #Loop$((x--))/" $file
elif [[ "${arr[$i]}" =~ ^[$IFS]*(if|case) ]]
then sed -i $l"s/$/ #Selection$((++y))/" $file
elif [[ "${arr[$i]}" =~ ^[$IFS]*(fi|esac) ]]
then sed -i $l"s/$/ #Selection$((y--))/" $file
fi
done <$file
答案 1 :(得分:-1)
你可以测试一下;
echo "enter full file name: "
read file
getArray(){
arr=()
while IFS= read -r line
do
arr+=("$line")
done < "$1"
}
getArray $file
echo "What file looks like before editing"
printf "%s\n" "${arr[@]}" #Test function to see if array works (it does)
#Declare variables
x=1
y=1
#Start main loop
for (( i=0; i<${#arr[@]}; i++ ));
do
#echo $i "====" ${arr[$i]}
#echo "-------"
#echo "x"$x
if [[ "${arr[$i]}" == "while"* ]] || [[ "${arr[$i]}" == "until" ]]
then
sed -i "$((i+1))s/$/ #Loop $x/" $file
let "x++"
continue;
fi
if [[ "${arr[$i]}" == *"for"* ]]
then sed -i "$((i+1))s/$/ #Loop'$x'/" $file && let "x++"
continue
fi
if [[ "${arr[$i]}" == *"done"* ]]
then sed -i "$((i+1))s/$/ #Loop'$((x-1))'/" $file
continue
fi
if [[ "${arr[$i]}" == *"if"* ]] || [[ "${arr[$i]}" == *"case"* ]]
then
if [[ "${arr[$i]}" != *"elif"* ]]
then
sed -i "$((i+1))s/$/ #Selection'$y'/" $file && let "y++"
fi
continue
fi
if [[ "${arr[$i]}" == *"fi"* ]] || [[ "${arr[$i]}" == *"esac"* ]]
then sed -i "$((i+1))s/$/ #Selection'$((y-1))'/" $file
continue
fi
done < $file