Henk Valk
Henk Valk

Reputation: 85

how to round the output in shell?

For our webshop we get from the manufacturers a csv file (automatically updated) with product data. Some manufacturers use prices without Tax and some within.

I want to change prices with a shell script to add 21% TAX and round it to nearest .95 or .50

For example I get a sheet:

sku|ean|name|type|price_excl_vat|price

EU-123|123123123123|Product name|simple|24.9900

I use this code:

sed -i "1 s/price/price_excl_vat/" inputfile
awk '{FS="|"; OFS="|"; if (NR<=1) {print $0 "|price"} else {print $0 "|" $5*1.21}}' inputfile > outputfile

the output is:

sku|ean|name|type|price_excl_vat|price

EU-123|123123123123|Product name|simple|24.9900|30.2379

How do I round it to the correct price like below ?

sku|ean|name|type|price_excl_vat|price

EU-123|123123123123|Product name|simple|24.9900|29.95

Upvotes: 0

Views: 749

Answers (3)

karakfa
karakfa

Reputation: 67497

awk to the rescue!

 awk 'BEGIN      {FS=OFS="|"} 
      $NF==$NF+0 {a=$NF*1.21; 
                  r=a-int(a); 
                  if      (r<0.225) a=a-r-0.05; 
                  else if (r<0.725) a=a-r+0.50; 
                  else              a=a-r+0.95; 
                  $(NF+1)=a} 1'

note that in your example the nearest number for 30.2379 will be 30.50 Perhaps you want to round down?

To round down instead of the nearest, and with a variable price column. The new computed value will be appended to the end of the row.

 awk 'BEGIN    {FS=OFS="|"; k=5} 
      $k==$k+0 {a=$k*1.21; 
                r=a-int(a); 
                if      (r<0.50) a=a-r-0.05; 
                else if (r<0.95) a=a-r+0.50; 
                else             a=a-r+0.95; 
                $(NF+1)=a} 1'

Upvotes: 1

David W.
David W.

Reputation: 107040

Not knowing what you're program looks like, it makes it difficult to give you more information.

However, both awk and bash have the printf command. This command can be used for rounding floating point numbers. (Yes, Bash is integer arithmetic, but it can pretend a number is a decimal number).

I gave you the link for the C printf command because the one for Bash doesn't include the formatting codes. Read it and weep because the documentation is a bit dense, and if you've never used printf before, it can be quite difficult to understand. Fortunately, an example will bring things to light:

$ foo="23.42532"
$ printf "%2.2f\n", $foo
$ 23.43   #All rounded for you!

The f means it's a floating point number. The % tells you that this is the beginning of a formatting sequence. The 2.2 means you want 2 digits on the left side of the decimal and two digits on the right. If you said %4.2f, it would make sure there's enough room for four digits on the left side of the decimal, and left pad the number with spaces. The \n on the end is the New Line character.

Fortunately, although printf can be hard to understand at first, it's pretty much the same in almost all programming languages. It's in awk, Perl, Python, C, Java, and many more languages. And, if the information you need isn't in printf, try the documentation on sprintf which is like printf, but prints the formatted text into a string.

The best documentation I've seen is in the Perl sprintf documentation because it gives you plenty of examples.

Upvotes: 1

NeronLeVelu
NeronLeVelu

Reputation: 10039

awk '#define field separator in and out
     BEGIN{FS=OFS="|"}

     # add/modify a 6th field for price label if missing on header only
     NR==1 && NF == 6 { $6 = "price"; print; next}
     NR==1 && NF == 5 { $6 = "price"; print; next}

     # add price with tva rounded to 0.01 if missing
     NF == 5 { $6 = int( $5 * 121 ) / 100 }

     # print the line (modified or not, ex empty lines) [7 is just a *not 0*)
     7
    ' inputfile \
 > outputfile
  • self documented
  • not sure about your sed for header becasue sample show already a header with price so take the one you want

Upvotes: 1

Related Questions