在 awk 中包含函数库
include library of functions in awk
还有很多常用的函数(尤其是arithmetic/mathematics)没有内置awk
需要一直自己写
例如:
- 没有
c=min(a,b)
,所以在awk
中我不断地写c=a<b?a:b
- 最大值相同,即
c=max(a,b)
- 绝对值相同,即
c=abs(a)
所以我必须不断地写 c=a>0?a:-a
- 等等....
理想情况下,我可以将这些函数写入一个 awk
源文件,然后 "include" 将其写入我所有的 awk 实例,这样我就可以随意调用它们。
我查看了 GNU gawk
的“@include”功能,但它只执行包含的脚本中的任何内容 - 即我无法调用函数。
我希望写一些功能,例如mylib.awk
,然后 "include" 这个每当我调用 awk
.
我尝试了 -f mylib.awk
选项到 awk
,但是脚本被执行了 - 其中的函数不可调用。
使用 GNU awk:
$ ls lib
prims.awk
$ cat lib/prims.awk
function abs(num) { return (num > 0 ? num : -num) }
function max(a,b) { return (a > b ? a : b) }
function min(a,b) { return (a < b ? a : b) }
$ export AWKPATH="$PWD/lib"
$ awk -i prims.awk 'BEGIN{print min(4,7), abs(-3)}'
4 3
$ cat tst.awk
@include "prims.awk"
BEGIN { print min(4,7), abs(-3) }
$ awk -f tst.awk
4 3
您可以有多个 -f program-file
选项,因此一个可以是您常用的函数,另一个可以是解决特定问题的 awk 脚本,它将访问这些函数。
awk -f common-funcs.awk -f specific.awk file-to-process.txt
我不知道这是否是您要找的,但这是我想到的最好的。这是一个例子:
$ cat common_func.awk
# Remove spaces from front and back of string
function trim(s) {
gsub(/^[ \t]+/, "", s);
gsub(/[ \t]+$/, "", s);
return s;
}
$ cat specific.awk
{ print , }
{ print trim(), trim() }
$ cat file-to-process.txt
abc | def |
2$ awk -F\| -f common_func.awk -f specific.awk file-to-process.txt
abc def
abc def
对于常规 awk(非 gnu),您不能将 -f program-file
选项与 inline 程序混合使用。也就是说,以下将不起作用:
awk -f common_func.awk '{ print trim() }' file-to-process.txt # WRONG
正如评论中所指出的,但是,对于 gawk,您可以将 -f
选项与 -e
:
一起使用
awk -f file.awk -e '{stuff}' file.txt
如果您不能使用 EdMorton 建议的 -i
(如果您的 awk < 4.1
版本),请尝试使用 GNU Awk 3.1.7
--source program-text
Provide program source code in the program-text. This option allows you to mix source code in files with source code that you enter
on the command line. This is particularly useful when you have library
functions that you want to use from your command-line programs
$ awk --version
GNU Awk 3.1.7
Copyright (C) 1989, 1991-2009 Free Software Foundation.
$ cat primes.awk
function abs(num) { return (num > 0 ? num : -num) }
function max(a,b) { return (a > b ? a : b) }
function min(a,b) { return (a < b ? a : b) }
$ awk -f primes.awk --source 'BEGIN{print min(4,7), abs(-3)}'
4 3
在常规 awk(非 gnu)上,您仍然可以使用 shell 将文件的 cat 伪装成 'code'(通常在前面,但可能无处不在)因为它尊重工作顺序的 awk 方式)
> cat /tmp/delme.awk
function PrintIt( a) { printf( "#%s\n", a )}
> echo "aze\nqsd" | awk "$( cat /tmp/delme.awk)"'{ sub( /./, ""); PrintIt( [=10=] )}'
#ze
#sd
对于 GNU awk,您可以使用 -i 命令行选项或从脚本内部使用 @include 指令,但如果您想要 POSIX 解决方案,那么 awk -f functions.awk -f script.awk file.txt 是你需要走的路。
还有很多常用的函数(尤其是arithmetic/mathematics)没有内置awk
需要一直自己写
例如:
- 没有
c=min(a,b)
,所以在awk
中我不断地写c=a<b?a:b
- 最大值相同,即
c=max(a,b)
- 绝对值相同,即
c=abs(a)
所以我必须不断地写c=a>0?a:-a
- 等等....
理想情况下,我可以将这些函数写入一个 awk
源文件,然后 "include" 将其写入我所有的 awk 实例,这样我就可以随意调用它们。
我查看了 GNU gawk
的“@include”功能,但它只执行包含的脚本中的任何内容 - 即我无法调用函数。
我希望写一些功能,例如mylib.awk
,然后 "include" 这个每当我调用 awk
.
我尝试了 -f mylib.awk
选项到 awk
,但是脚本被执行了 - 其中的函数不可调用。
使用 GNU awk:
$ ls lib
prims.awk
$ cat lib/prims.awk
function abs(num) { return (num > 0 ? num : -num) }
function max(a,b) { return (a > b ? a : b) }
function min(a,b) { return (a < b ? a : b) }
$ export AWKPATH="$PWD/lib"
$ awk -i prims.awk 'BEGIN{print min(4,7), abs(-3)}'
4 3
$ cat tst.awk
@include "prims.awk"
BEGIN { print min(4,7), abs(-3) }
$ awk -f tst.awk
4 3
您可以有多个 -f program-file
选项,因此一个可以是您常用的函数,另一个可以是解决特定问题的 awk 脚本,它将访问这些函数。
awk -f common-funcs.awk -f specific.awk file-to-process.txt
我不知道这是否是您要找的,但这是我想到的最好的。这是一个例子:
$ cat common_func.awk
# Remove spaces from front and back of string
function trim(s) {
gsub(/^[ \t]+/, "", s);
gsub(/[ \t]+$/, "", s);
return s;
}
$ cat specific.awk
{ print , }
{ print trim(), trim() }
$ cat file-to-process.txt
abc | def |
2$ awk -F\| -f common_func.awk -f specific.awk file-to-process.txt
abc def
abc def
对于常规 awk(非 gnu),您不能将 -f program-file
选项与 inline 程序混合使用。也就是说,以下将不起作用:
awk -f common_func.awk '{ print trim() }' file-to-process.txt # WRONG
正如评论中所指出的,但是,对于 gawk,您可以将 -f
选项与 -e
:
awk -f file.awk -e '{stuff}' file.txt
如果您不能使用 EdMorton 建议的 -i
(如果您的 awk < 4.1
版本),请尝试使用 GNU Awk 3.1.7
--source program-text
Provide program source code in the program-text. This option allows you to mix source code in files with source code that you enter on the command line. This is particularly useful when you have library functions that you want to use from your command-line programs
$ awk --version
GNU Awk 3.1.7
Copyright (C) 1989, 1991-2009 Free Software Foundation.
$ cat primes.awk
function abs(num) { return (num > 0 ? num : -num) }
function max(a,b) { return (a > b ? a : b) }
function min(a,b) { return (a < b ? a : b) }
$ awk -f primes.awk --source 'BEGIN{print min(4,7), abs(-3)}'
4 3
在常规 awk(非 gnu)上,您仍然可以使用 shell 将文件的 cat 伪装成 'code'(通常在前面,但可能无处不在)因为它尊重工作顺序的 awk 方式)
> cat /tmp/delme.awk
function PrintIt( a) { printf( "#%s\n", a )}
> echo "aze\nqsd" | awk "$( cat /tmp/delme.awk)"'{ sub( /./, ""); PrintIt( [=10=] )}'
#ze
#sd
对于 GNU awk,您可以使用 -i 命令行选项或从脚本内部使用 @include 指令,但如果您想要 POSIX 解决方案,那么 awk -f functions.awk -f script.awk file.txt 是你需要走的路。