为什么这个在 CentOS 上运行的 awk 脚本不能在 Ubuntu 上运行?

为什么这个在 CentOS 上运行的 awk 脚本不能在 Ubuntu 上运行?

(供参考,代码可能也在这里: https://github.com/garyexplains/examples 这可能比视频更好。)


有什么原因吗这个简单的脚本CentOS 上的无法在 Ubuntu 上运行吗?

[nsaunders@rolly awk]$ 
[nsaunders@rolly awk]$ awk -f loop.awk numbers.txt 
1 2 3 
1 2 3 4 5 6 7 
1 2 3 4 5 6 7 8 9 10 11 12 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 

[nsaunders@rolly awk]$ 
[nsaunders@rolly awk]$ cat loop.awk 
func printlist(n) {
    for(i=1;i<=n;i++) {
        printf("%d ",i)
    }
    printf("\n")
}


{printlist($1)}

[nsaunders@rolly awk]$ 
[nsaunders@rolly awk]$ cat numbers.txt 
3
7
12
15
16
31

[nsaunders@rolly awk]$ 

我越来越:

awk: loop.awk: line 11: function printlist never defined
awk: loop.awk: line 11: function printlist never defined

Ubuntu 上的 awk 版本:

mawk 1.3.4 20200120
Copyright 2008-2019,2020, Thomas E. Dickey
Copyright 1991-1996,2014, Michael D. Brennan

random-funcs:       srandom/random
regex-funcs:        internal
compiled limits:
sprintf buffer      8192
maximum-integer     2147483647

在 CentOS 机器上:

[nsaunders@rolly ~]$ 
[nsaunders@rolly ~]$ awk -W version
GNU Awk 4.2.1, API: 2.0 (GNU MPFR 3.1.6-p2, GNU MP 6.1.2)
Copyright (C) 1989, 1991-2018 Free Software Foundation.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
[nsaunders@rolly ~]$ 

无论您使用什么机器,情况awk都差不多吗?awk

答案1

正如GNU Awk 用户指南

在许多 awk 实现中,包括 gawk,关键字function可以缩写为func。(ce)但是,POSIX 仅指定使用关键字function

awk因此,错误可能是因为您的 Ubuntu 系统上的实现是mawk,或者某些东西(例如POSIXLY_CORRECT环境变量)正在影响gawk您系统上的行为。

mawkUbuntu 过去默认使用awk- 但据我所知,所有当前支持的版本都gawk默认使用。如果您mawk通过包管理系统安装,您应该能够使用该update-alternatives机制来查询/设置默认 ex。

update-alternatives --query awk

sudo update-alternatives --config awk

答案2

不管你使用的是哪台机器,awk 不都是 awk 吗?

不,您甚至可能在同一个系统上有多个实现。gawk(GNU Awk)有许多 中没有的功能mawk。您遇到的那个并不是唯一的一个。gawk文档包含各主要 AWK 实现中不同的常见特性列表。

作为steeldriver 说,使用 来func作为 的缩写,function部分 AWK 实现支持,但并非所有实现都支持。要解决这个特定问题,最好的办法就是将其更改func为。通过这一更改,您的脚本可以像 一样function使用。mawkgawk

如果由于某种原因你不能或不想这样做,或者如果您需要其他未gawk提供的非标准功能mawk,您可以使用gawk该包所提供的gawk

gawk -f loop.awk numbers.txt

正如steeldriver的回答所示,您可以使用update-alternativesawk解决gawk而不是mawk(或者在您安装时可能会自动发生gawk)。

但是,你正在使用awk -f,所以如果你愿意添加一条线到 AWK 脚本的顶部并将脚本标记为可执行(chmod +x loop.awk),然后您可以让它指定应该使用哪个解释器:

#!/usr/bin/awk -f

func printlist(n) {
    for(i=1;i<=n;i++) {
        printf("%d ",i)
    }
    printf("\n")
}

{printlist($1)}

然后使用以下命令运行脚本:

./loop.awk numbers.txt

那么其他脚本就不会受到影响。

对于这个只有一次出现func关键字的小脚本,可以将其写为function,添加 shebang 可能不是您的最佳选择,除非您无论如何都要这样做。但是,对于需要gawk中不存在的功能的更复杂情况mawk,我建议您考虑这样做。添加 shebang 还有一个好处,那就是可以明确您希望使用哪种 AWK 实现,而对于与此无关且编写为可移植的脚本,可以使用 shebang #!/usr/bin/awk -f

(当然,具有此类shebang的脚本在更广泛意义上并不是完全可移植的,因为它们假设awk在中/usr/bin。)

相关内容