Solved

# multiplying or dividing all values in the last column of a file using one liner perl script in linux

Posted on 2011-09-20
325 Views
I'm using the code below to add or subtract values from each value in the last column of data in a 4 column file (see attached). Instead of adding/subtracting how would I divide or multiply? Would be as simply as replacing the the minus with a * or / next to the number I wanted the value mutliplied or divided by?

``````[user@server ~]\$ perl -alne 'BEGIN{\$i=pop}(\$F[3]+=\$i)>0 or \$F[3]=0; print "@F"' file1.txt -0.468 > file1b.txt
``````
0
Question by:libertyforall2
• 3
• 2
• 2

LVL 84

Expert Comment

yes
0

Author Comment

Ok. One more quick question. I just realized I will need to add/subtract a value if the data point is zero else multiply/divide by a different value. Lets say add 3.2 if zero else divide by .8 for all values in the final column.
0

LVL 11

Accepted Solution

tel2 earned 250 total points
Hi lfa2,

Regarding your first question, if you're asking if you could do this:
perl -alne 'BEGIN{\$i=pop}(\$F[3]+=\$i)>0 or \$F[3]=0; print "@F"' file1.txt *0.468 > file1b.txt
and this:
perl -alne 'BEGIN{\$i=pop}(\$F[3]+=\$i)>0 or \$F[3]=0; print "@F"' file1.txt /0.468 > file1b.txt
then my answer would be: No.  I think that argument after the input file (e.g. -0.468) must be just a number (which can be +ve or -ve), otherwise I think you'd be doing maths like:
\$F[3]+=/.8    (ie: \$F[3] = \$F[3] + /.8)
which doesn't make sense to me.

For your second question, does this work for you?:
perl -alne 'BEGIN{\$mult=pop;\$add=pop};\$F[3] = (\$F[3]==0 ? eval("\$F[3]\$add") : eval("\$F[3]\$mult")); print "@F"' file1.txt +3.2 /.8 >file1b.txt
0

LVL 84

Assisted Solution

ozo earned 250 total points
perl -alne 'BEGIN{\$i=pop}if(\$F[3]){\$F[3]+=3.2}else{\$F[3]/=\$i}; print "@F"' file1.txt .8 > file1b.txt
0

LVL 11

Expert Comment

As you may have noticed lfa2, my solutions assume you want to supply the +3.2 and /.8 as arguments (i.e. after the code):

Here's a slightly more efficient one (the 1st "eval" was not needed):
perl -alne 'BEGIN{\$mult=pop;\$add=pop};\$F[3] = \$F[3]==0 ? \$F[3]+=\$add : eval "\$F[3]\$mult"; print "@F"' file1.txt -3.2 /.8 >file1b.txt

And if you are always going to be dividing (never multiplying), it could be further simplified to:
perl -alne 'BEGIN{\$div=pop;\$add=pop}\$F[3] = \$F[3]==0 ? \$F[3]+\$add : \$F[3]/\$div; print "@F"' file1.txt +3.2 .8 >file1b.txt

Which can be compressed to:
perl -alne 'BEGIN{\$d=pop;\$a=pop}\$F[3]=\$F[3]==0?\$F[3]+\$a:\$F[3]/\$d;print"@F"' file1.txt +3.2 .8

Or if you're always going to be multiplying:
perl -alne 'BEGIN{\$m=pop;\$a=pop}\$F[3]=\$F[3]==0?\$F[3]+\$a:\$F[3]*\$m;print"@F"' file1.txt +3.2 1.25
As you can see, I'm multiplying by 1.25, which is the same as dividing by .8.
0

LVL 11

Expert Comment

Append:
>file1b.txt
to my last 2 solutions, pls lfa2.
0

Author Closing Comment

Works
0

## Join & Write a Comment Already a member? Login.

### Suggested Solutions

Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
A short article about problems I had with the new location API and permissions in Marshmallow
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

#### 762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

#### Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!