我正在尝试创建一个脚本,该脚本将删除充满状态信息和其他各种文本的 txt 文件的某些部分。我无法结束主要的 if 语句。另外,我试图通过将 date 命令放入生成 output.txt 的脚本中来删除最旧的状态信息。有没有办法让它删除最旧的信息。我主要是想让 if 语句结束。谢谢。 (另外,我最初将 else if 作为 elif 的,但我得到了相同的结果。)
./count.sh:第 30 行:意外标记else' ./count.sh: line 30:
else附近的语法错误
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
else if [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
else
echo "You're good, homie. It's under 500"
fi
答案1
这里的问题是,通过使用else if
而不是elif
,您将在程序中添加嵌套,并且需要添加更多fi
语句来终止附加条件语句。
这是程序的编辑版本,缩进略有不同,以演示我的意思
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
else
if [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
fi
fi
fi
else
echo "You're good, homie. It's under 500"
fi
或者,你可以使用elif
WCOUNT=$(wc -l output.txt $1 | awk '{print $1}')
if [[ $WCOUNT -gt 50 ]]; then
if [[ "grep CLIENTSTART output.txt" != null ]]; then
echo $WCOUNT
sed -i '/\*\*\*CLIENTSTART/,/CLIENTEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep DHCPSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DHCPSTART/,/DHCPEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep DNSSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*DNSSTART/,/DNSEND\*\*\*/ d' output.txt
echo $WCOUNT
elif [[ -n "grep WEBSTART output.txt" ]]; then
echo $WCOUNT
sed -i '/\*\*\*WEBSTART/,/WEBEND\*\*\*/ d' output.txt
echo $WCOUNT
else
echo "Cannot help you"
fi
else
echo "You're good, homie. It's under 500"
fi
(另外,稍微挑剔一下,您正在检查是否有超过 50 行,但您的输出消息表明您正在检查 500 行。虽然从技术上讲,有不到 500 行,但这有点误导:p)
编辑:正如其他人指出的那样,这将修复您的语法错误,但脚本仍然存在其他问题。我也建议阅读他们的评论/答案。
答案2
您收到语法错误的原因是您的else if
语句应该是elif
.
如果给出wc -l
两个文件,它将产生三行输出:
$ wc -l .profile .profile
30 .profile
30 .profile
60 total
这会影响第一个未加引号if
的测试$WCOUNT
,并且其扩展会引入另一个语法错误。
你可能想要
WCOUNT=$( wc -l <output.txt )
此外,您还对字符串进行了许多测试,例如"grep DHCPSTART output.txt"
.这些测试将总是是真实的。
要测试文件中是否存在字符串,请使用
if grep -Fq 'fixed string' filename; then
例如
if grep -Fq 'CLIENTSTART' output.txt; then
# do something
elif grep -Fq 'DHCPSTART' output.txt; then
# do something
else
# do something
fi
停止产生任何实际输出-q
。grep
它的退出状态将告诉是否找到该字符串,这就是使该if
语句起作用的原因(该标志还使grep
在第一次匹配时停止读取文件)。该-F
标志使grep
给定模式视为固定字符串而不是正则表达式。
对脚本内部结构的建议:
tmpfile=$(mktemp)
for string in CLIENT DHCP DNS WEB; do
if grep -Fq "${string}START" output.txt; then
sed "/\*\*\*${string}START/,/${string}END\*\*\*/d" \
output.txt >"$tmpfile"
break
fi
done
if [ -s "$tmpfile" ]; then
mv "$tmpfile" output.txt
else
echo 'Can not help you'
rm -f "$tmpfile"
fi
[ -s "$tmpfile" ]
如果文件$tmpfile
的大小大于零(sed
调用时将具有该大小),则测试将成功。
for
带有 的循环模仿break
您的if ... then ... elif
逻辑,但以更紧凑的方式。