这个脚本有效。
$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 list
或cut -d= -f2 < list
,或者,如果您愿意,可以是<list cut -d= -f2
。echo $i
应该是echo "$i"
(参见https://mywiki.wooledge.org/Quotes)。- 始终运行您的代码http://shellcheck.net直到您更加熟悉 shell。