EB2127
EB2127

Reputation: 1858

Is there an alternative way to express whole line $0 in awk?

I have a tab-delimited file old.txt whereby I am adding a column header and value.

$ cat old.txt
Sepal length    Sepal width Petal length    Petal width Species
5.1 3.5 1.4 0.2 I. setosa
4.9 3.0 1.4 0.2 I. setosa
4.7 3.2 1.3 0.2 I. setosa
4.6 3.1 1.5 0.2 I. setosa
5.0 3.6 1.4 0.2 I. setosa

I would like to add a column with header and contents with awk. I've been using the following command:

awk 'NR==1 {printf("%s\t%s\n", $0, "name")}  NR>1 {printf("%s\t%s\n", $0, "ABC") }'  old.txt > new.txt

which should output the following:

Sepal length    Sepal width Petal length    Petal width Species name
5.1 3.5 1.4 0.2 I. setosa   ABC
4.9 3.0 1.4 0.2 I. setosa   ABC
4.7 3.2 1.3 0.2 I. setosa   ABC
4.6 3.1 1.5 0.2 I. setosa   ABC
5.0 3.6 1.4 0.2 I. setosa   ABC

My current problem is that I am trying to emped this command in a Groovy string for an application. However, apparently $0 is an illegal term within a string in Groovy:

illegal string body character after dollar sign;
   solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}"

This is the groovy code which is causing the problem:

"""
awk 'NR==1 {printf("%s\t%s\n", $0, "name")}  NR>1 {printf("%s\t%s\n", $0, "ABC") }'  old.txt > new.txt
"""

So, I am asking:

(1) Is there another way to represent $0 in awk?

(2) Perhaps there's another command to do this entirely?

Upvotes: 0

Views: 507

Answers (2)

Keith Thompson
Keith Thompson

Reputation: 263367

$0 is a perfectly valid character sequence within a string in Groovy. It's just not valid in a string literal.

If you want to represent $0 in a Groovy string, write it as "\$0".

Or you could use a single-quoted Groovy string literal, which doesn't support interpolation. For example, '$0' and "\$0" have the same value. (This could be a problem if you need single quotes in the string.)

(No, as far as I know there's no other way to refer to $0 in awk.)

UPDATE:

Now that you've shown (a fragment of) your Groovy code, I believe you can fix it by changing both occurrences of """ to '''.

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 754190

Using awk

There isn't another way to directly refer to $0 in awk. You can, however, use $zero, where zero is a variable explicitly set to zero that will, therefore, provide an indirect reference — $zero refers to $0. It's a little 'edgy', though.

awk 'NR == 1 {zero=0; printf("%s\t%s\n", $zero, "name")}
     NR  > 1 {printf("%s\t%s\n", $zero, "ABC") }'  old.txt

At least on macOS 10.14.6 Mojave, the explicit zero=0; is needed (either there or in a BEGIN section) — otherwise, the complaint is:

awk: illegal field $(), name "zero"

Presumably, it is interpreting it as an empty string instead of as a zero; the context isn't sufficiently 'numeric' to get it interpreted as zero.

Using sed

You could use sed:

sed -e '1s/$/      name/' \
    -e '2,$s/$/    ABC/' old.txt

where the long sequences of blanks within the s/// commands would each be replaced by a tab in some suitable way. You can write it all on one line if brevity is more important than clarity; you could use a single -e option likewise (and then the -e is no longer crucial either).

Interaction with Groovy

Both these avoid $ followed by digits — will Groovy complain about $zero, $s or $/?

Upvotes: 2

Related Questions