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"

相關內容