awk:同じブロック内のifと条件文

awk:同じブロック内のifと条件文

ファイル名が「pretempsc.cfg」であることを確認し、その内容をそのまま印刷する必要があるスクリプトコードは次のとおりです。 。他のファイルの場合は、「abcを無効にする...」で始まる行だけを「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と条件付きアクションを誤って使用したようですが、正確に何が間違っているのかはわかりません。

注:シェルスクリプトでawkを使用する必要があり、IN_FILEを独自に処理するWhatFileIsItなどの他の関数もたくさんありました。

ベストアンサー1

はい、対応するパターン一致を文全体に変更する必要がありますif

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

/pattern/はい$0 ~ /pattern/$0入力行全体を含む略語です。)

printそれ以降に入力された4列目のみが印刷されるため、justno abcabc disable foo bar dooなりますno abc bar。これがあなたが望むものかどうかはわかりません。


これを行う間、いくつかの他のことが浮かび上がります。あまりにも明確であるか、スクリプトの残りの部分と競合する場合は無視してかまいません。 (あまりにも多くの間違いを犯さないことを願っています。)

最後に余分な閉じカッコがあるようで、print最も深い条件のインデントが少し外れたようで少し書き直します。

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

しかし、ここから特別なことをする唯一の時間は両方とも!scnode真で/^abc disable/一致する場合であり、他のすべての場合にのみprint条件を組み合わせることができます&&(もちろん、異なる種類のファイル間の分離はもはや必要ありません)。とても明確です)。

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

next実行時間を短縮するaがあるため、finalは節なしにそのまま維持できprintelse実際には全体のコードブロックが1つなので、条件if文をメインレベルに上げて無条件に基本印刷ジョブを実行できます。

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

(もちろん今はちょっときれいに見えるかもしれません。)


また、シェルスクリプトでは猫を邪魔する必要はありません。猫を眠らせ、リダイレクトにシェルを使用する方が良いです。 (そしてシェル変数を引用してください。)

 WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"

関数の名前は少し混乱しています。実際に「何」についての質問に答えずにファイルを処理します。たぶん似たものでしょうかProcessFile

さて、関数について言えば、関数はIN_FILEローカルではなく変数を使用します。 2つの異なるファイルに対して関数を実行する必要がある場合は、混乱する可能性があります。シェルスクリプト自体と同様に、関数もパラメータを使用して呼び出すことができ、MyFunction foo関数内に $1含めることができます。foo

だから私はおそらく次のことをします:

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

(入力リダイレクトをawkコマンドラインの途中に配置するか、最後に配置するかは関係ありません。)

以下と組み合わせて使用​​:

ProcessFile "$IN_FILE" > "$OUT_FILE"

おすすめ記事