Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

include library of functions in awk

Tags:

awk

There are many common functions (especially arithmetic/mathematics) that are not built into awk that I need to write myself all the time.

For example:

  1. There is no c=min(a,b) , so in awk i constantly write c=a<b?a:b
  2. same for maximum i.e. c=max(a,b)
  3. same for absolute value i.e. c=abs(a) so i have to constantly write c=a>0?a:-a
  4. and so on....

Ideally, I could write these functions into an awk source file, and "include" it into all of my instances of awk, so I can call them at will.

I looked into the "@include" functionality of GNU's gawk , but it just executes whatever is in the included script - i.e. I cannot call functions.

I was hoping to write some functions in e.g. mylib.awk, and then "include" this whenever I call awk.

I tried the -f mylib.awk option to awk, but the script is executed - the functions therein are not callable.

like image 404
cmo Avatar asked Feb 11 '15 19:02

cmo


People also ask

How do I run awk command specified in a file?

Running Long Programs In order to tell awk to use that file for its program, you type: awk -f source-file input-file1 input-file2 … The -f instructs the awk utility to get the awk program from the file source-file (see Command-Line Options). Any filename can be used for source-file .

What is the awk function?

Awk is mostly used for pattern scanning and processing. It searches one or more files to see if they contain lines that matches with the specified patterns and then perform the associated actions. Awk is abbreviated from the names of the developers – Aho, Weinberger, and Kernighan.

Is awk part of GNU?

GNU AWK may be the most widely deployed version because it is included with GNU-based Linux packages.


2 Answers

With 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
like image 192
Ed Morton Avatar answered Oct 14 '22 08:10

Ed Morton


You can have multiple -f program-file options, so one can be your common functions and the other can be a specific problem solving awk script, which will have access to those functions.

awk -f common-funcs.awk -f specific.awk file-to-process.txt

I don't know if this is what you were looking for, but it's the best I've come up with. Here's an example:

$ 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 $1, $2 }
{ print trim($1), trim($2) }

$ 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

With regular awk (non-gnu) you can't mix the -f program-file option with an inline program. That is, the following won't work:

awk -f common_func.awk '{ print trim($1) }' file-to-process.txt # WRONG 

As pointed out in the comments, however, with gawk you can use the -f option together with -e:

awk -f file.awk -e '{stuff}' file.txt
like image 7
jas Avatar answered Oct 14 '22 08:10

jas