-1

i have many simple text file(with extension .txt) that consists of 6 rows and 7 columns as given below

   0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 9.3 2.2  2.0 1.4 2.5 9.6
  30.00 9.3 2.2  1.2 1.5 1.9 1.4
  30.00 9.3 2.2  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5

I want to do some manipulations using column3(row 3,4,5) and column2(row 3,4,5) without disturbing row 1,2 and 6 . Additionally there will be always same number in third,four fifth rows of column 3 and column 2.

At first i want to increase the value of row 3,4,5 of column3 (for example in above text file from 2.2 to 3.4) with step 0.2 for every .txt files and want to multiply it by 1.6 and want to place the multiplied output in column2(row 3,4,5)

For example:

in the original input file column3(row 3,4,5) values are 2.2 but want to increase from 2.2 to 2.4(0.2 increment),then expected output would be

 0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 3.84 2.4  2.0 1.4 2.5 9.6
  30.00 3.84 2.4  1.2 1.5 1.9 1.4
  30.00 3.84 2.4  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5

Again increase 0.2 then the expected output would be

   0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 4.16 2.6  2.0 1.4 2.5 9.6
  30.00 4.16 2.6  1.2 1.5 1.9 1.4
  30.00 4.16 2.6  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5
  

i tried the code below:, after referencing text manipulation by addition and multiplication

    #!/bin/bash
  for file in /home/se/data/*.txt
  do 
    for val in $(seq 2.2 0.2 3.4)
    do
      awk -vval=$val -vadd=0.2 -vsmul=1.6 '{
        if(NR==1 || NR==2) {
          $3=val;
          $2=$3
        } else if(NR>=3 && NR<=5) {
          $3=val+add;
          $2=$3
        } else $3=$3;
        print
      }' test_file > output$val
    done
 done

But i am getting some error,hppe somebody will come forward to help me.Thanks.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • 1
    Sure. Is this the _some error_ you're getting?: `awk: fatal: cannot open file 'test_file' for reading (No such file or directory)`? (not my downvote, btw) – James Brown Oct 13 '20 at 06:21
  • 2
    Please don't make more work for others by vandalizing your posts. By posting on the Stack Exchange (SE) network, you've granted a non-revocable right, under the [CC BY-SA license](https://creativecommons.org/licenses/by-sa/4.0), for SE to distribute the content (regardless of your future choices). By SE policy, the non-vandalized version is distributed. Thus, any such destructive edits will be reverted. Please see [How does deleting work?](https://meta.stackexchange.com/q/5221) for more information on how deleting content works on this site. – Ryan M Oct 13 '20 at 07:02

2 Answers2

2

To increment the 3rd field by 0.2, all you need is:

awk '{$1=$1}; NR >= 3 && NR <= 5 { $3+=.2; }1' file

The rule $1=$1 simply forces awk to recalculate the field removing any leading/trailing whitespace from the other rows. Rows (records) 3-5 update the value of the 3rd field by 0.2 and then the 1 at the end invokes the default print.

Example Input

$ cat file
   0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 9.3 2.2  2.0 1.4 2.5 9.6
  30.00 9.3 2.2  1.2 1.5 1.9 1.4
  30.00 9.3 2.2  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5

Example Use/Output

$ awk '{$1=$1}; NR >= 3 && NR <= 5 { $3+=.2; }1' file
0.00 5.8 2.0 5.0 6.0 8.0 0.0
10.00 5.8 2.0 1.0 1.0 1.2 9.6
10.00 9.3 2.4 2.0 1.4 2.5 9.6
30.00 9.3 2.4 1.2 1.5 1.9 1.4
30.00 9.3 2.4 3.2 2.4 1.2 4.1
60.00 9.8 3.5 1.4 2.7 3.2 4.5

Note, if preserving the original spacing is a requirement, you can use sub() to replace the 3rd field through it takes a bit more to ensure there is no other text with that value in the record.

Assuming there are no other fields before the third-field (e.g. fields 1, or 2) with the same value as the third field, you could do:

$ awk 'NR >= 3 && NR <= 5 { sub($3,$3+.2) }1' file
   0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 9.3 2.4  2.0 1.4 2.5 9.6
  30.00 9.3 2.4  1.2 1.5 1.9 1.4
  30.00 9.3 2.4  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Glad to help. `awk` is a veritable Swiss-Army Knife of text processing. There is very little it cannot do on its own. (except... editing files in-place is probably the only area it lacks -- but then again, it was never meant to do that...) – David C. Rankin Oct 13 '20 at 07:08
  • On GNU awk inplace editing, see: https://stackoverflow.com/questions/16529716/save-modifications-in-place-with-awk – James Brown Oct 13 '20 at 09:08
  • 1
    @JamesBrown, yes GNU provides a facility to do that -- but with the smattering of awks that don't, I've treated it a bit like quantum gravity.... Here, with the edit and the output going to the `output$val` filename -- we didn't have to mess with the quantum gravity `:)` – David C. Rankin Oct 13 '20 at 09:22
0

by converting the pattern-action-block into a straight up multiplication, it saves the hassle of extra { $1 = $1 } up front and } 1' at the end of it for printing.

The extra trailing underscore ))_' is to force a string concat in order to guard against the exclusion-from-output scenario when the updated $3 is a numeric zero.

echo '   
  0.00 5.8 2.0  5.0 6.0 8.0 0.0
  10.00 5.8 2.0  1.0 1.0 1.2 9.6
  10.00 9.3 2.2  2.0 1.4 2.5 9.6
  30.00 9.3 2.2  1.2 1.5 1.9 1.4
  30.00 9.3 2.2  3.2 2.4 1.2 4.1
  60.00 9.8 3.5  1.4 2.7 3.2 4.5' | 

mawk '($3 += (2 < NR) * 0.2 * (NR < 6))_'

0.00 5.8 2 5.0 6.0 8.0 0.0
10.00 5.8 2 1.0 1.0 1.2 9.6
10.00 9.3 2.4 2.0 1.4 2.5 9.6
30.00 9.3 2.4 1.2 1.5 1.9 1.4
30.00 9.3 2.4 3.2 2.4 1.2 4.1
60.00 9.8 3.5 1.4 2.7 3.2 4.5

other approaches include using the logical ORs (||), or the ternary if-?-then-:-else operator instead :


gawk '5 < NR || NR < 3 || ($3 += 0.2)^_'

nawk '(5 < NR) < (2 < NR) ? ($3 += 0.2)^_ : !_'

RARE Kpop Manifesto
  • 2,453
  • 3
  • 11