awk:if和条件语句在同一块中

awk:if和条件语句在同一块中

这是脚本的代码,我必须检查文件名是否为“pretempsc.cfg”并按原样打印其内容。 。对于任何其他文件,我只应该将以“abc disable ...”开头的行修改为“no abc ...”。

    #!/bin/sh
    IN_FILE=$1
    OUT_FILE=$2

    WhatFileIsIt() {
    awk -v filename=$IN_FILE '
    BEGIN {
        scnode = 0;
        if (filename == "pretempsc.cfg") {
            scnode = 1; }
    }
    {
        if (!scnode) {
            /^abc disable/ {
            print "no abc "$4"";
            next;
            }

            print;}
        }
        else {print}
    }
    '
    }

    cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE

执行此脚本时,我收到以下错误:

 awk: cmd. line:9:         /^abc disable/ {
 awk: cmd. line:9:                        ^ syntax error
 awk: cmd. line:16:     else {print}
 awk: cmd. line:16:     ^ syntax error

从我所能查到的情况来看,我怀疑我在操作块中使用 if 和条件操作是错误的,但我无法弄清楚到底出了什么问题。

需要注意的是:我必须在 shell 脚本中使用 awk,并且还有很多类似于 WhatFileIsIt 的其他函数对 IN_FILE 进行自己的处理。

答案1

是的,您需要将该模式匹配更改为完整if语句:

if (/^abc disable/) {
    print "no abc "$4"";
    next;
}

/pattern/是 的简写$0 ~ /pattern/,其中$0包含整个输入行。)

请注意,printthere 仅打印之后输入的第四列no abc,因此abc disable foo bar doo变为 just no abc bar。我不确定这是否是您想要的。


当我们这样做时,一些其他事情浮现在脑海中......如果它们太明显或与脚本的其余部分冲突,请随意忽略其中任何一个。 (希望我没有犯太多错误。)

我认为 的末尾有一个额外的右大括号print,而且最深条件的缩进似乎有点偏离,所以稍微重写一下:

{
    if (!scnode) {
        if (/^abc disable/) {
            print "no abc " $4;
            next;
        }
        print;
    } else {
        print;
    }
}

但从这里开始,似乎唯一一次做特殊的事情是当两者都!scnode为 true 并且/^abc disable/匹配时,在所有其他情况下只有print.因此我们可以将条件与&&(当然不同类型文件之间的分隔不再那么清晰。):

{
    if (!scnode && /^abc disable/) {
        print "no abc "$4"";
        next;
    } else {
        print;
    }
}

由于有 anext可以缩短执行时间,finalprint可以在没有else子句的情况下保持不变,事实上,由于整个代码块只是一个if,我们可以将条件放到主级别,然后执行无条件默认打印操作。

!scnode && /^abc disable/ {
    print "no abc "$4"";
    next;
}
1;

(当然,现在看起来可能有点太简洁了。)


另外,在 shell 脚本中,您不需要打扰猫,最好让它们睡觉并仅使用 shell 进行重定向。 (并引用 shell 变量。)

 WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"

该函数的名称有点令人困惑,它并没有真正回答任何“什么”问题,而是处理一个文件。也许类似ProcessFile

好吧,说到函数,该函数使用变量IN_FILE,该变量不是它的本地变量。如果需要为两个不同的文件运行一个函数,可能会令人困惑。与 shell 脚本本身一样,函数也可以带参数,调用MyFunction foo, 使$1包含foo在函数内部。

所以我可能会做类似的事情

ProcessFile() {
awk < "$1" -v filename="$1" '
[...]

(将输入重定向放在 awk 命令行的中间或末尾都没有关系。)

与以下产品一起使用:

ProcessFile "$IN_FILE" > "$OUT_FILE"

相关内容