figuring out an awk one liner

I have googled around a bit and could not find an answer to how this works:

echo $STRING | awk '$0=$NF' FS=

I know what each part is doing. The record is being set to equal the last field and the field separator is being set to null so that each character is considered a field. Why can FS= be put at the end like that though? I presume that the '$0=$NF' is used as a pattern match. Perhaps my problem is more with the syntax as I am used to using awk more like:

   awk '/string/ { # some code etc. }'

Thanks,
Ben

Not as a pattern match, it prints the last character if it is unequal to "" or 0. Everything in awk has the form condition{action} . If the condition evaluates to 1 then the action is performed. If the action is omitted then the default action is performed, which is {print $0} .
So this is equivalent to:

awk '$0=$NF{print $0}' FS=
1 Like

That's an old-fasioned way of setting variables in awk. Setting a blank field-separator means, in some versions of awk, to split on every single character.

So what it's actually doing, is setting the entire line($0) to the last field($NF), and printing if it's anything but blank.

So I'd expect this to just print the last character of a line all the time.

I don't think this is a very efficient usage. Never use awk to process one single line if you can help it, that's lighting a furnace to burn a hair; modern enough shells have builtins which can do this without the overhead of running an entire process.

1 Like

Thanks. I realize the result. I am trying to work out why. I know that $0 is being set to the last character because the field separator has been set to null and $0 is being set to the last field. But I am not used to the way it has been written (i.e. without {...} etc.). I presume it is outputting each record by default. I am still a little confused about this one liner. Any further clarification would be appreciated.

Thanks,
Ben

---------- Post updated at 10:51 AM ---------- Previous update was at 10:43 AM ----------

Ah. That was the main part which was puzzling me. Is it handled like doing a -vFS= and can this method of variable assignment be relied on for different platforms?

Thanks,
Ben

---------- Post updated at 11:01 AM ---------- Previous update was at 10:51 AM ----------

I agree. I know I can do this: echo ${STRING#${STRING%?}} or in ksh I can do: typeset -R1 c=$STRING; echo $c. Coming across this line in awk that I couldn't completely understand though bothered me.

Ben

This method of assigning variables can be relied upon, and I think it is more convenient than -v, but note that the variable will not be available in the BEGIN section. The special meaning of setting FS to an empty string, does not work in every awk..

1 Like