Home > Software engineering >  Awk multiply integers in geometric sequence in each cell
Awk multiply integers in geometric sequence in each cell

Time:10-27

I have a dataframe like this

0 1 0 1 0 0....
1 1 1 1 0 0
0 0 1 1 0 1
.
.
.

And I want to multiply each of them with a geometric sequence

1, 10, 100, 1000, 10000 ... 10^(n-1)

so the result will be

0 10 0 1000 0 0....
1 10 100 1000 0 0
0 0 100 1000 0 100000
.
.
.

I have tried with

awk '{n=0 ; x=0 ; for (i = 1; i <= NF; i  ) if ($i == 1)  {n=10**i ; x = x n } print x }' test.txt

But the results were not what I expected

enter image description here

CodePudding user response:

With GNU awk:

awk '{for (i=1; i<=NF; i  ){if($i==1){n=10**(i-1); $i=$i*n}} print}' test.txt

Output:

0 10 0 1000 0 0
1 10 100 1000 0 0
0 0 100 1000 0 100000

CodePudding user response:

What you wrote is absolutely not what you want. Your awk program parses each line of the input and computes only one number per line which happens to be 10 times the integer you would see if you were writing the 0's and 1's in reverse order. So, for a line like:

1 0 0 1 0 1

your awk program computes 10 0 0 10000 0 1000000=1010010. As you can see, this is the same as 10 times 101001 (100101 reversed).

To do what you want you can loop over all fields and modify them on the fly by multiplying them by the corresponding power of 10, as shown in the other answer.

Note: another awk solution, a bit more compact, but strictly equivalent for your inputs, could be:

awk '{for(i=1;i<=NF;i  ) $i*=10**(i-1)} {print}' test.txt

The first block loops over the fields and modifies them on the fly by multiplying them by the corresponding power of 10. The second block prints the modified line.

  • Related