Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

awk - restricting area in file, printing

I have a large input which part looks like:

SUM OF ABSOLUTE VALUES OF CHECKS IS 0.844670D-13


                      Input-Output in F Format

No.  Curve    Input Param.        Correction     Output Param.    Standard Deviation
 9      0     43.8999000000     -0.2148692026     43.6850307974      0.1066086900
10      0      0.0883000000     -0.0081173828      0.0801826172      0.0006755954
11      0      2.5816650000      0.1530838229      2.7347488229      0.0114687081
15      0      0.2175000000      0.0018561462      0.2193561462      0.0017699976
16      0     80.4198910000      3.4449399961     83.8648309961      0.1158732928
20      0      1.9424000000      0.3078499311      2.2502499311      0.0047924544
23      0      3.5047300000      0.4315780848      3.9363080848      0.0052905759
24      0      5.5942300000      1.8976306735      7.4918606735      0.0092102115
26      0  54804.4046000000     -0.0029799077  54804.4016200923      0.0006133608


                      Input-Output in D Format

No.  Curve    Input Param.        Correction     Output Param.    Standard Deviation
 9      0  0.4389990000D+02 -0.2148692026D+00  0.4368503080D+02  0.1066086900D+00
10      0  0.8830000000D-01 -0.8117382819D-02  0.8018261718D-01  0.6755954153D-03
11      0  0.2581665000D+01  0.1530838229D+00  0.2734748823D+01  0.1146870812D-01
15      0  0.2175000000D+00  0.1856146162D-02  0.2193561462D+00  0.1769997586D-02
16      0  0.8041989100D+02  0.3444939996D+01  0.8386483100D+02  0.1158732928D+00
20      0  0.1942400000D+01  0.3078499311D+00  0.2250249931D+01  0.4792454358D-02
23      0  0.3504730000D+01  0.4315780848D+00  0.3936308085D+01  0.5290575930D-02
24      0  0.5594230000D+01  0.1897630674D+01  0.7491860674D+01  0.9210211480D-02
26      0  0.5480440460D+05 -0.2979907673D-02  0.5480440162D+05  0.6133608199D-03 

I would like to print a column of numbers from the first table from column $5 and $6. I would like to applicate an arithmetic operations for numbers on rows 11, 15 and 20 and print these results instead of number in the table. I have a code:

BEGIN {  CONVFMT="%0.17f" }

/D Format/ { exit }

$1 ==  9 { prt(1,1) }
$1 == 10 { prt(1,1) }
$1 == 11 { prt(180,3.141592653589) }
$1 == 15 { prt(100,1) }
$1 == 16 { prt(1,1) }
$1 == 20 { prt(10,1) }
$1 == 23 { prt(1,1) }
$1 == 24 { prt(1,1) }
$1 != 26 { prt(1,1) }

function prt(mult, div) {
    print trunc($5 * mult / div) ORS trunc($6 * mult / div)
}

function trunc(n,       s) {
    s=index(n,".")
    return (s ? substr(n,1,s+6) : n)
}

I would like to get an output:

43.685030
0.106608
0.080182
0.000675
156.68965
0.657068
21.935614
0.176999
83.864830
0.115873
22.502499
0.047924
3.936308
0.005290
7.491860
0.009210

but I am getting these number twice and I haven't got good restricted area in file. So my questions are: 1) How to print numbers from tables only one times. I mean this 16 numbers:

$1 ==  9 { prt(1,1) }
$1 == 10 { prt(1,1) }
$1 == 11 { prt(180,3.141592653589) }
$1 == 15 { prt(100,1) }
$1 == 16 { prt(1,1) }
$1 == 20 { prt(10,1) }
$1 == 23 { prt(1,1) }
$1 == 24 { prt(1,1) }

2) How to restict an area that the program should works with table between strings /F Format/ to /D Format/? Thank you very much.

Eddited code

BEGIN {  CONVFMT="%0.17f" }

/D Format/ { exit }

$1 ==  9 { prt(1,1); next }
$1 == 10 { prt(1,1); next }
$1 == 11 { prt(180,3.141592653589); next }
$1 == 15 { prt(100,1); next }
$1 == 16 { prt(1,1); next }
$1 == 20 { prt(10,1); next }
$1 == 23 { prt(1,1); next }
$1 == 24 { prt(1,1); next }
$1 != 26 && $1 + 0 > 0 { prt(1,1); next }

function prt(mult, div) {
    print trunc($5 * mult / div) ORS trunc($6 * mult / div)
}

function trunc(n,       s) {
    s=index(n,".")
    return (s ? substr(n,1,s+6) : n)
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem of duplicate outputs is due to a single line matching both its own number and the $1 != 26 condition in the end. A simple solution is to add ; next after each prt(…) call.

The problem with zero outputs is likewise due to the $1 != 26 matching too much. You could, for example, add additional conditions to this line (such as $1 != 26 && $1 + 0 > 0).

These changes should produce the desired output. Other than that, the script has a lot of redundancy that could be optimised (e.g., all the { prt(1,1); next } lines could be merged into one with a more complex condition), but that may not be worthwhile for a one-off script.

edit: For example, this could be a complete set of pattern lines for this example:

/D Format/ { exit }
!($1 ~ /^[1-9]/) { next }
$1 == 26 { next }
$1 == 11 { prt(180,3.141592653589); next }
{ prt(1,1) }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...