Thanos
Thanos

Reputation: 586

Print every second consequtive field in two columns - awk

Assume the following file

#zvview.exe
#begin Present/3
 77191.0000 189.320100          0          0          3          0111110 16    1
-8.072430+6-8.072430+6      77190          0          1         37111110 16    2
         37          2                                            111110 16    3
 8.115068+6 0.000000+0 8.500000+6 6.390560-2 9.000000+6 6.803440-1111110 16    4
 9.500000+6 1.685009+0 1.000000+7 2.582780+0 1.050000+7 3.260540+0111110 16    5
         37          2                                            111110 16   18

What I would like to do, is print in two columns, the fields after line 6. This can be done using NR. The tricky part is the following : Every second field, should go in one column as well as adding an E before the sign, so that the output file will look like this

8.115068E+6 0.000000E+0
8.500000E+6 6.390560E-2
9.000000E+6 6.803440E-1
9.500000E+6 1.685009E+0
1.000000E+7 2.582780E+0
1.050000E+7 3.260540E+0

From the output file you see that I want to keep in $6 only length($6)=10 characters.

How is it possible to do it in awk?

Upvotes: 0

Views: 98

Answers (3)

Thanos
Thanos

Reputation: 586

I tried to combine @karafka 's answer using substr, so the following does the trick!

awk 'NR>=6 && NR<=7{$6=substr($6,1,10);for(i=1;i<=6;i+=2) print substr($i,1,8) "E" substr($i,9) FS substr($(i+1),1,8) "E" substr($(i+1),9)}' file

and the output is

8.115068E+6 0.000000E+0
8.500000E+6 6.390560E-2
9.000000E+6 6.803440E-1
9.500000E+6 1.685009E+0
1.000000E+7 2.582780E+0
1.050000E+7 3.260540E+0

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203219

With GNU awk for FIELDWIDTHS:

$ cat tst.awk
BEGIN { FIELDWIDTHS="9 2 9 2 9 2 9 2 9 2 9 2" }
NR>5 && NR<8 {
    for (i=1;i<NF;i+=4) {
        print $i "E" $(i+1), $(i+2) "E" $(i+3)
    }
}

$ awk -f tst.awk file
 8.115068E+6  0.000000E+0
 8.500000E+6  6.390560E-2
 9.000000E+6  6.803440E-1
 9.500000E+6  1.685009E+0
 1.000000E+7  2.582780E+0
 1.050000E+7  3.260540E+0

If you really want to get rid of the leading blanks then there's various ways to do it (simplest being gsub(/ /,"",$<field number>) on the relevant fields) but I left them in because the above allows your output to line up properly if/when your numbers start with a -, like they do on line 4 of your sample input.

If you don't have GNU awk, get it as you're missing a LOT of extremely useful functionality.

Upvotes: 2

karakfa
karakfa

Reputation: 67467

can do all in awk but perhaps easier with the unix toolset

$ sed -n '6,7p' file | cut -c2-66 | tr ' ' '\n' | pr -2ats' '

8.115068+6 0.000000+0
8.500000+6 6.390560-2
9.000000+6 6.803440-1
9.500000+6 1.685009+0
1.000000+7 2.582780+0
1.050000+7 3.260540+0

Here is a awk only solution or comparison

$ awk 'NR>=6 && NR<=7{$6=substr($6,1,10);
                      for(i=1;i<=6;i+=2) {f[++c]=$i;s[c]=$(i+1)}}
                  END{for(i=1;i<=c;i++) print f[i],s[i]}' file

8.115068+6 0.000000+0
8.500000+6 6.390560-2
9.000000+6 6.803440-1
9.500000+6 1.685009+0
1.000000+7 2.582780+0
1.050000+7 3.260540+0

Perhaps shorter version,

$ awk 'NR>=6 && NR<=7{$6=substr($6,1,10); 
                      for(i=1;i<=6;i+=2) print $i FS $(i+1)}' file

8.115068+6 0.000000+0
8.500000+6 6.390560-2
9.000000+6 6.803440-1
9.500000+6 1.685009+0
1.000000+7 2.582780+0
1.050000+7 3.260540+0

to convert format to standard scientific notation, you can pipe the result to sed or embed something similar in awk script (using gsub).

... | sed 's/[+-]/E&/g'

8.115068E+6 0.000000E+0
8.500000E+6 6.390560E-2
9.000000E+6 6.803440E-1
9.500000E+6 1.685009E+0
1.000000E+7 2.582780E+0
1.050000E+7 3.260540E+0

Upvotes: 2

Related Questions