
這是腳本的程式碼,我必須檢查檔案名稱是否為“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
包含整個輸入行。)
請注意,print
there 僅列印之後輸入的第四列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"