仅在条件已满的情况下执行脚本执行

时间:2020-02-11 13:33:20

标签: bash

我有下一个脚本

./students.sh |awk '{print $1,$4}'
CLARA
MARC [Found]
STEVE [Found]
GREG [FOUND]
JAKE
#IF FOUND PEFORM ->
./students.sh -move  

我需要创建一个条件,其中-move标志仅在MARC STEVE和GREG的状态为FOUND时才应用, 在其他情况下,什么也不做。

1 个答案:

答案 0 :(得分:1)

执行此类常规任务的一种方法是使用上一个程序的退出代码来确定是否执行下一个程序。

一般而言:

if anycommand; then
    anothercommand 
fi

anothercommand仅在anycommand成功时才执行,这取决于任何命令的退出代码。

如果需要,

awk可以以非零状态退出。举一个简单的例子:

/MARC/ {
    # Successful exit immediately if MARC is found
    exit 0
}
/CRAM/ {
    # Failure exit immediately if CRAM is found
    exit 1
}

如果找到MARC STEVE和GREG,则您的任务然后将awk代码写入exit 0,否则将exit 1写入。默认退出代码为0,因此请确保您明确地exit 1(如果它们并不全部存在)。

if ./students.sh | awk 'your code here'; then
    ./students.sh -move  
fi

您也可以对此“短路”。如果前一个命令以状态0退出,则两个与号告诉外壳程序仅执行./students -move

./students.sh | awk 'your code here' && ./students.sh -move

编辑:当Charles Duffy发表评论时,您一定要注意。请通读他在评论中链接到的帖子。 这是如何组织awk代码的示例。如所写,它区分大小写,因此“ MARC [FOUND]”不会触发成功。另外,没有锚点,因此“ ARAMARC [Found]”将触发成功,而不仅仅是“ MARC [Found]”。您必须加强代码来处理这些情况,但是希望这会有所帮助。

/MARC \[Found\]/ {
    # Set flag to true
    marc = 1
}
/STEVE \[Found\]/ {
    steve = 1
}
/GREG \[Found\]/ {
    greg = 1
}
END {
    if (marc && steve && greg) {
        # Successful exit if all 3 are found
        exit 0
    }
    # Failure exit otherwise
    exit 1
}

编辑2 :您可能已经注意到上述解决方案的扩展性不是很好。对于检查三个学生,这还不错。但是,如果要检查“找到”了10,000名学生,该解决方案将是站不住脚的。如果您正在寻找一个可扩展的解决方案,我将研究创建一个名为“ required.dat”的排序文件,其中包含需要找到的学生。运行./students.sh脚本时,将其通过管道传输到awk '$4 ~ /\[Found\]/ {print $1}' | sort > found.dat。这将与找到的学生一起创建另一个文件。然后运行N_REQ_NOT_FOUND=$(comm -23 required.dat found.dat | wc -l)以查找需要但未找到的学生数量。如果$ N_REQ_NOT_FOUND大于0,则意味着某些学生是必需的,但找不到。