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) {
  ....

相关内容