You seem to think that awk
treats its input as a multiline string. It doesn't. When you run an awk script on a file, the script is applied to each line of the file separately. So, your gensub
was run once per line. You can actually do what you want with awk
but it really isn't the best tool for the job.
As far as I can tell, you have a large file and only want to print a number that comes after mark:
and whitespace. If so, all of these approaches are simpler than fooling around with gensub
:
Use grep
with Perl Compatible Regular Expressions (-P
)
$ grep -oP 'mark:\s*\K\d+' file
98
The -o
makes grep
only print the matching portion of the line. The \K
is a PCRE construct which means "ignore anything matched before this point".
sed
$ sed -n 's/.*mark:\s*\([0-9]\+\).*/\1/p' file
98
The -n
suppresses normal output. The p
at the end makes sed
print only if the substitution was successful. The regex itself captures a string of numbers following mark:
and 0 or more whitespace characters and replaces the whole line with what was captured.
Perl
$ perl -ne 'print if s/.*mark:\s*(\d+).*/$1/' file
98
The -n
tells perl to read an input file line by line and apply the script given by -e
. The script will print any lines where the substitution was successful.
If you really, really want to use gensub
, you could do something like:
$ awk '/mark:/{print gensub(/.*mark:\s*([0-9]+).*/,"\\1","g")}' file
98
Personally, I would do it this way in awk:
$ awk '/mark:/{gsub(/[^0-9]/,"");print}' file
98
Since you seemed to be trying to get awk to receive multiline input, this is how you can do that (assuming there are no NULL characters in your file):
$ awk '{print(gensub(/^.*mark: ([0-9]+).*$/,"\\1","g"))}' RS='\0' file
98
The RS='\0'
sets the input record separator (that's what defines a "line" for awk
) to \0
. Since there are no such characters in your file, this results in awk
reading the whole thing at once.