不确定是否可行,但我试图突破if
循环中的while
语句。我不想退出while
循环。我尝试使用exit
和break
,但都退出了while循环。
问题是我不知道我要查找的文件位于哪个文件夹中,这就是为什么我想在匹配搜索到的文件时退出当前的if
语句,以便我可以转到下一个序列号。
我有一个名为drives-fw-sn.txt
的文本文件,其中包含序列号列表。代码细分:
drives-fw-sn.txt
循环从while
一次读取一个序列号output_log
find
的文件
这是我的代码片段(有三个以上的测试文件夹)。请注意,它仍然包含退出exit
循环的while
命令。
while read node; do
if find ./test1/*log* -maxdepth 2 -type f -name output_log -exec egrep -m 1 $node {} \; ; then
echo "Log SN $node available"
exit 1
fi
if find ./test2/*log* -maxdepth 2 -type f -name output_log -exec egrep -m 1 $node {} \; ; then
echo "Log SN $node available"
exit 1
fi
if find ./test3/*log* -maxdepth 2 -type f -name output_log -exec egrep -m 1 $node {} \; ; then
echo "Log SN $node available"
exit 1
fi
done < drives-fw-sn.txt
答案 0 :(得分:1)
本身无法突破if
。但是从您的示例的外观来看,您可以使用continue
命令而不是exit
来立即迭代循环。
答案 1 :(得分:1)
使用内置的return
实际上非常简单。在while
循环内,在一个小的功能块中设置if
语句。在迭代期间满足if
条件时,您可以让它调用return
,其中脚本将返回到调用函数的位置并从该点继续。我将向您展示一个例子:
#!/bin/bash
read -p 'Input: ' HEY
func() { if true; then return; fi; }
while true; do
echo "Input received!"
func && break
done
在func
函数中,您有一个非常基本的if
语句,可以保存您想要的任何条件值,例如您的多个条件。当您添加return
关键字时,if
语句会发送解释程序&#34;程序计数器&#34;,如果愿意,则返回{{1}函数被调用。在这种情况下,在func
循环内。所以就好像甚至没有调用函数一样,你可以看到,while循环中的下一个命令是一个while
关键字,它将结束break
循环。包含while
代码的函数可以在if-then-return
循环内部或外部,只要放在while
语句中的条件已经首先加载到解释器中(bash读取脚本)从上到下,类似于C代码的加载方式。)
还有一个惰性方法,即将整个脚本代码包装在main函数中,这样您就可以在脚本中的任何位置使用if
,无论它是循环还是条件语句。以下是以这种方式修改的上述脚本的示例:
return
以这种方式执行此操作将有助于将变量保持在本地而不是创建全局变量。要做到这一点,在#!/bin/bash
MAIN() {
read -p 'Input: ' HEY
while true; do
if [ "$HEY" == "hello" ]; then
return
else
echo "Incorrect input! Try again!"
MAIN
fi
done
}
MAIN
echo "Correct input received!"
函数中的任何一点,您都可以将变量定义为局部变量,因此它只保存MAIN
函数运行时给定的值。函数完成后,变量及其值不再存在。
希望这有帮助。
答案 2 :(得分:0)
continue
是您如何“突破”if
声明的具体问题的正确答案。请注意,if
检查实际上并未检查grep是否成功,请参阅chepner的评论。
我会以一种首先解决问题的方式来做到这一点:
由于您不知道包含序列号的文件将位于哪个目录中,因此您查看它们的顺序无关紧要。不是单独列出所有目录并在每个目录上运行find -exec
,而是让grep直接尝试所有日志文件:
while read -r node; do
cat **/output_log | grep -m 1 "$node" && echo "Log SN $node available"
done < drives-fw-sn.txt
这需要globstar shell选项shopt -s globstar
来启用**/
构造。根据您的目录结构,您甚至可能不需要它,而是可以使用类似test*/*log*/output_log
的内容。
cat
用于防止grep在找到匹配后检查其他文件。
输出略有不同:匹配以文件名为前缀,但可以使用相应的grep选项(-h
来调整)来抑制文件名。
看起来你也不需要正则表达式匹配;如果是这样,您可以将grep -F
用于固定字符串,这应该更快。
最后,根据序列号的外观,您可能希望使用-w
选项(仅匹配完整的单词)以避免因子字符串匹配而产生误报。