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

Nic*_*ers 7 bash scripts awk text-processing

(作为参考,代码也可能在这里: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]$ 
Run Code Online (Sandbox Code Playgroud)

我越来越:

awk: loop.awk: line 11: function printlist never defined
awk: loop.awk: line 11: function printlist never defined
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在 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 ~]$ 
Run Code Online (Sandbox Code Playgroud)

不管你在什么机器上,不是awk很重要awk吗?

ste*_*ver 20

GNU Awk 用户指南中所述

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

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

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

update-alternatives --query awk

sudo update-alternatives --config awk
Run Code Online (Sandbox Code Playgroud)


Eli*_*gan 9

不管你在什么机器上,awk 都不是 awk 吗?

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

正如steeldriver 所说的func那样function,一些但并非所有的 AWK 实现都支持using作为 for 的缩写。要解决这个特殊问题,最好的办法就是更改funcfunction. 与单一的变化,你的脚本工作mawk,以及gawk

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

gawk -f loop.awk numbers.txt
Run Code Online (Sandbox Code Playgroud)

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

但是,您正在使用awk -f,因此如果您愿意在 AWK 脚本的顶部添加一条 shebang 行并标记脚本可执行文件 ( chmod +x loop.awk),那么您可以让它指定应该使用哪个解释器:

#!/usr/bin/awk -f

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

{printlist($1)}
Run Code Online (Sandbox Code Playgroud)

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

#!/usr/bin/awk -f

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

{printlist($1)}
Run Code Online (Sandbox Code Playgroud)

然后其他脚本不受影响。

对于这个只出现一次func可以写为的关键字的小脚本function,添加shebang 可能不是您的最佳选择,除非您无论如何都打算这样做。但是,对于需要 中gawk不存在的功能的更复杂的情况mawk,我建议考虑它。添加 shebang 还有助于阐明您希望使用的 AWK 实现,并且一个无关紧要且编写为可移植的脚本可以具有#!/usr/bin/awk -fshebang。

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