我在 for 循环中使用 if 条件。如果 if 条件返回 yes,那么我想再次转到 for 循环的开头。这在 bash 中可能吗?
#!/bin/bash
for i in /apps/incoming/*.sql
do
j=$(egrep "[A-Z]{6}[ ]{1}[@abc_id]{10}[ ]{1}[=]{1}[ ]{1}[0-9]*" $i | awk '{ print $4 }')
#echo $j
#Query database
export ORACLE_HOME=/apps/uc/tmd/oracle/instantclient_11_2
export LD_LIBRARY_PATH=/apps/uc/tmd/oracle/instantclient_11_2
sqlplus=/apps/oracle/instantclient_11_2/sqlplus
tmprnt=$($sqlplus -s abcsd/sakfdj@'(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = odsakjfldkjf)(PORT = 1111)))(CONNECT_DATA =(SERVICE_NAME = SFDDFD)(SRVR = DEDICATED)))' << EOF
SELECT name from blabla where abc_id='$j';
EOF)
if `echo ${tmprnt} | grep "${searchString1}" 1>/dev/null 2>&1`
then
GO TO the start of FOR IN loop and run the query again.
因此,如果 IF 条件内的上述 tmprnt 变量与搜索字符串匹配,那么我想再次运行该内容(SQL 查询有时返回“未选择行”,但在我们再次运行时它会以某种方式返回正确的结果)。我知道 bash 中没有 GO TO。请建议一条出路。
答案1
如果您想继续下一个查询,请使用该continue
语句。
如果要重复相同的查询,请使用循环。您想要重复查询,因此请编写一个执行此操作的脚本,而不是使用您所使用的语言中根本不存在的低级构造来掩盖您的意图。
for i in /apps/incoming/*.sql
do
while
j=$(…)
…
! echo "${tmprnt}" | grep "${searchString1}" 1>/dev/null 2>&1
do
… # whatever you want to do when $tmprnt has the right format
done
done
我将您编写的条件语句更正为您可能的意思 - 执行输出grep
没有意义。还记住在变量和命令替换两边加上双引号。
请注意这里的逻辑:而搜索字符串是不是存在,重复查询。
该脚本将在一个紧密的循环中查询数据库,因此这里缺少一些东西(希望您只是省略了代码以使问题简单)。
答案2
是的,有一种方法,但您永远不应该在正在开发的新脚本中使用它,因为它只是一种解决方法。
然而,当我在桌面上从 Windows 迁移到 Linux 时,我有很多预先存在的.BAT
文件.CMD
需要转换,并且我不打算为它们重写逻辑,所以我成立goto
一种在 bash 中执行的方法是有效的,因为它会自行goto function
运行sed
以删除脚本中不应运行的任何部分,然后对其进行全部评估:
#!/bin/bash
# BAT / CMD goto function
function goto
{
label=$1
cmd=$(sed -n "/^:[[:blank:]][[:blank:]]*${label}/{:a;n;p;ba};" $0 |
grep -v ':$')
eval "$cmd"
exit
}
apt update
# Just for the heck of it: how to create a variable where to jump to:
start=${1:-"start"}
goto "$start"
: start
goto_msg="Starting..."
echo $goto_msg
# Just jump to the label:
goto "continue"
: skipped
goto_msg="This is skipped!"
echo "$goto_msg"
: continue
goto_msg="Ended..."
echo "$goto_msg"
# following doesn't jump to apt update whereas original does
goto update
我一点也不感到内疚,正如莱纳斯·托瓦兹 (Linus Torvalds) 所说的那样:
发件人:Linus Torvalds
主题:回复:有机会进行 2.6.0-test* 吗?
日期:2003 年 1 月 12 日星期日 11:38:35 -0800(太平洋标准时间)我认为 goto 很好,而且它们通常比大量缩进更具可读性。那是尤其如果代码流实际上并不是自然缩进(在本例中是这样,所以我认为使用 goto 没有任何意义),则为 true更清晰不是,但一般来说 goto 的可读性非常好)。
当然,在像 Pascal 这样的愚蠢语言中,标签不能具有描述性,goto 可能很糟糕。但这不是goto的错,这是语言设计者的脑残。