How to use awk '{print $1*Number}' from the second line or telling him to ignore NaN values?

Viewed 6401

I have a file called 'waterproofposters.jsonl' with this type of output:

Regular price
100
200
300
400
500

And I need to take out 2% of each value. I have used the following code:

awk '{print $1*0.98}' waterproofposters.jsonl 

And then I have the following output:

0
98
196
294
392
490

And then I'm stuck because I need to have 'Regular price' in the first line instead '0'

I thought to replace '0' with 'Regular price using

find . -name "waterproof.jsonl" | xargs sed -i -e 's/0/Regular price/g'

But it will replace all the '0' by 'Regular price'

3 Answers

To print the first line as-is:

awk '{print (NR>1 ? $0*0.98 : $0)}'

To print lines that are not a number as-is:

awk '{print ($0+0 == $0 ? $0*0.98 : $0)}'

I'm using $0 instead of $1 in the multiplication because:

  1. They're the same thing in your numerical input, and
  2. I aesthetically prefer using the same value across the whole script rather than different values for the numeric vs non-numeric lines, and
  3. When you use a specific field it causes awk to do field-splitting so it's a bit more efficient to not reference a field when the whole record will do.

Here's both of the above working with the posted sample input:

$ awk '{print (NR>1 ? $0*0.98 : $0)}' file
Regular price
98
196
294
392
490

$ awk '{print ($0+0 == $0 ? $0*0.98 : $0)}' file
Regular price
98
196
294
392
490

and here's the difference between the two given input that has a non-numeric value mid input file:

$ cat file
Regular price
100
200
foobar
400
500

$ awk '{print (NR>1 ? $0*0.98 : $0)}' file
Regular price
98
196
0
392
490

$ awk '{print ($0+0 == $0 ? $0*0.98 : $0)}' file
Regular price
98
196
foobar
392
490

You can certainly achieve what you need with a single awk call, but an answer to why your sed -i -e 's/0/Regular price/g' command did not work as expected is that you used 0 as the regex pattern. 0 matches any zero char inside the string.

You want to replace 0s that are the only char on a line.

Hence, you need to use ^ and $ anchors to match the start and end of the line respectively:

sed -i 's/^0$/Regular price/'

If you need to replace on the first line only add the 1 address before the substitution command:

sed -i '1 s/^0$/Regular price/'

Note you do not need g, since you only expect one replacement per line and g is only needed when performing multiple replacements on a line. By default, all lines will get processed.

How to use awk '{print $1Number}' from the second line or telling him to ignore NaN values?*

I would do it following way using GNU AWK, let file.txt content be

Regular price
100
200
300
400
500

then

awk 'NR==1{print}NR>=2{print $1*0.98}' file.txt

output

Regular price
98
196
294
392
490

Explanation: if it 1st line just print it, if it 2nd or later line print 0.98 of 1st column value

(tested in GNU Awk 5.0.1)

Related