(for reference, the code is likely also here: https://github.com/garyexplains/examples which is probably a better source than a video.)
Would there be any reason why this simple script on CentOS wouldn't run on 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]$
I'm getting:
awk: loop.awk: line 11: function printlist never defined
awk: loop.awk: line 11: function printlist never defined
awk version on Ubuntu:
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
And on the CentOS machine:
[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 ~]$
isn't awk
pretty much awk
regardless of what machine you're on?
As noted in the The GNU Awk User’s Guide
So the error is possibly because the implementation of
awk
on your Ubuntu system ismawk
, or that something (such as aPOSIXLY_CORRECT
environment variable) is affecting howgawk
behaves on your system.Ubuntu used to ship with
mawk
as the defaultawk
- but as far as I know, all currently supported versions usegawk
by default. If you installedmawk
via the packaqge management system, you should be able to use theupdate-alternatives
mechanism to query/set the default ex.No, and you may even have multiple implementations on the same system.
gawk
(GNU Awk) has a number of features not present inmawk
. The one you've run into isn't the only one. Thegawk
documentation contains a list of common features that differ across major AWK implementations.As steeldriver says, using
func
as an abbreviation forfunction
is supported by some but not all AWK implementations. To solve this particular problem, the best thing to do is just changefunc
tofunction
. With that single change, your script works withmawk
as well asgawk
.If for some reason you can't or don't wish to do that, or if you need other nonstandard functionality that
gawk
provides butmawk
doesn't, you can usegawk
, which is provided by thegawk
package.As shown in steeldriver's answer, you can use
update-alternatives
to makeawk
resolve togawk
rather thanmawk
(or that may happen automatically when you installgawk
).However, you're using
awk -f
, so if you're willing to add a shebang line to the top of your AWK script and mark the script executable (chmod +x loop.awk
), then you can have it specify which interpreter ought to be used:You would then run the script with the command:
Then other scripts remain unaffected.
For this tiny script with a single occurrence of the
func
keyword that can be written asfunction
, adding a shebang probably isn't your best choice, unless you were going to do that anyway. For more complex situations where you needgawk
features not present inmawk
, though, I suggest considering it. Adding a shebang also has the benefit of clarifying what implementation of AWK you wish to be used, and a script for which this doesn't matter and that is written to be portable can have a#!/usr/bin/awk -f
shebang.(Of course, scripts with such shebangs aren't totally portable in the broader sense, since they assume
awk
is in/usr/bin
.)