else 命令的结果不起作用

else 命令的结果不起作用

这个脚本有效。

$cat list

IP address=192.3.xx.xx
IP address=192.4.xx.xx
IP address=192.19.xx.xx
IP address=192.22.xx.xx
$ cat myscript.sh

for i in `cat list | cut -d= -f2  | egrep '192.3|192.4'`
do
    if [ $? -eq 0 ]
    then
       echo $i
    else
       echo "no IP found"
    fi
done
$ ./myscript.sh

192.3.xx.xx
192.4.xx.xx

但如果将 192.3 和 192.4 更改为 192.8 等其他值,我应该得到:

no IP found

脚本返回时什么也没有。

我感谢您的帮助。谢谢

答案1

因此,如果有cat list | cut -d= -f2 | egrep '192.8',则 的输出egrep为空,并且命令替换将扩展为空。该for循环将有零个要循环的项目,循环体将不会运行,并且没有任何内容可打印“未找到”消息。

$?无论如何,在循环体开始时进行的测试并没有多大意义。确实,您正在第一次迭代中测试命令替换的退出状态,但在后面的迭代中,您正在测试上一次迭代的最后一个命令, with 可能不太有用。并不是说echo那里可能会失败,但如果你正在做其他事情,你可能会得到有趣的结果。

for i in `cat list | cut -d= -f2  | egrep '192.3|192.4'`
do
    if [ $? -eq 0 ]
    then
       # assume we're doing something more useful here
       echo "trying to do something with $i..."
       # but it happens to fail
       false
    else
       echo "no IP found"
    fi
done

输出是

trying to do something with 192.3.xx.xx...
no IP found

有点令人困惑。


如果循环没有找到任何内容,则运行“or else”部分的简单方法是在循环中设置一个标志并稍后进行测试,如下所示:

found=
key=192.8
for i in $(cat list | cut -d= -f2  | egrep "$key"); do
    found=1
    echo $i;
done
if [ -z "$found" ]; then
    echo nothing found
fi

尽管在这种情况下,这仍然有点愚蠢,因为循环for本质上所做的就是egrep逐项打印已经打印的相同内容(加上您依赖于分词正常工作,但您可能没有无论如何,全局字符)。

我想您可能正在对 IP 地址执行其他操作,但如果您只是要打印它们,您不妨直接使用输出egrep并检查退出状态以查看它是否匹配任何内容:

key=192.8
if ! cat list | cut -d= -f2  | egrep "$key"; then
    echo "nothing found"
fi

或者,将输出行读入数组并进行处理。在 Bash 中,您可以使用readarray

readarray -t ips < <(cat list | cut -d= -f2  | egrep "$key")
num=${#ips[@]}
if [ "$num" = 0 ]; then
    echo "zero items in list"
else 
    echo "found $num items"
fi
for ip in "${ips[@]}"; do
    echo "doing something with $ip..."
done

与 split+for 循环没有太大区别,但对于输入元素本身可能包含空格或通配符的情况更安全。

答案2

用于一般文本操作的强制性 POSIX 工具(即在所有 Unix 机器上可用)是awk。使用任何 awk:

$ awk -F'=' '$2 ~ /^192\.[34]\./{f=1; print $2} END{ if (!f) print "no IP found"; exit !f }' list
192.3.xx.xx
192.4.xx.xx

$ awk -F'=' '$2 ~ /^192\.[8]\./{f=1; print $2} END{ if (!f) print "no IP found"; exit !f }' list
no IP found

其他一些值得一提的事情:

  • egrep大约 20 年前已被弃用,取而代之的是grep -E,不要使用它。
  • 我认为你不明白@ChrisDavies 的评论是问题所在他指出仍然存在于你的问题中。
  • cat list | cut -d= -f2是一个联合大学,它应该是cut -d= -f2 listcut -d= -f2 < list,或者,如果您愿意,可以是<list cut -d= -f2
  • echo $i应该是echo "$i"(参见https://mywiki.wooledge.org/Quotes)。
  • 始终运行您的代码http://shellcheck.net直到您更加熟悉 shell。

相关内容