awk 指令中的 getline 使用安全嗎?

awk 指令中的 getline 使用安全嗎?

我在awk使用該函數的 SO 上發布答案時收到了奇怪的評論getline這裡是該答案的連結。

在發布我的答案後,一位用戶提出了以下評論,(我不是批評他。

這不是一個好的解決方案,無論內容如何,它都會連接行,並且在需要時不會處理更多行。並且您應該避免使用 getline。

它指出我們應該避免getline使用 中的函數awk。所以我的問題是,

  • getline在 awk 中使用函數安全嗎?
  • 什麼情況下應該使用,getline什麼情況下不應該使用?
  • 如果這個函數產生了意想不到的結果,那麼我們為什麼不提交錯誤報告呢?

答案1

大多數人爭論的焦點getline編碼風格地面。

這與awk讓程式碼一次處理一筆記錄的正常處理不同。

getline(當不用作getline var < "file"或時"cmd" | getline)在代碼語句中間拉入下一筆記錄(可能來自下一個文件)。人們很容易忘記這樣一個事實:它會增加 NR、FNR,並且可能會更改 FILENAME。

使用它時不要忘記的另一件事是檢查它的返回值,因為它會在 EOF 時返回 0 或在錯誤時返回 <0。

所以它不是getlineif/while (getline) ...,而是:

if/while ((getline) > 0) { .... }

或者:

if/while ((getline < "file") > 0) {...}

的大多數用法getline都可以透過使用類似狀態機的方法來扭轉。

代替:

/pattern/ {getline; print}

這可能是錯的,應該寫成:

/pattern/ && (getline) > 0 {print}

你會這樣做:

found_pattern {print; found_pattern=0}
/pattern/{found_pattern=1}

另請注意兩者有何不同,如果圖案匹配連續兩行。

現在,只要您意識到這一點,getline就可以了。如果您確實想同時處理多個文件,那麼您確實需要getline,但請記住檢查返回值:

while ((getline a < "a") > 0 && (getline b < "b") > 0) {
  ....

相關內容