简体   繁体   中英

Linux: Substitute text fields with values from other file

Alright, I cannot figure out how to do this.

I have a FileA which looks like this :

([7]RIMS_ID)                                            : "CNR"       
(refGain_A[7])                                          : 1           
(RIMSclockBias_A[7])                                    : -398015316.7
(RIMSclockDrift_A[7])                                   : -6442.29    
(RIMSclockSigma_A[7])                                   : .01         
(RIMSclockSigY_A[7])                                    : 0        

([8]RIMS_ID)                                            : "ABS"       
(refGain_A[8])                                          : 1           
(RIMSclockBias_A[8])                                    : -374515458
(RIMSclockDrift_A[8])                                   : -6442.29    
(RIMSclockSigma_A[8])                                   : .01         
(RIMSclockSigY_A[8])                                    : 0     

and so on where the [index] goes from 0 to 71 and each station has a different ID.

I want to replace the value corresponding to RIMSclockBias_A string of each station with a value I have on another file B like this:

CNR -44163754.49
ABS 3417370.112
...

So to have:

([7]RIMS_ID)                                            : "CNR"       
(refGain_A[7])                                          : 1           
(RIMSclockBias_A[7])                                    : -44163754.49
(RIMSclockDrift_A[7])                                   : -6442.29    
(RIMSclockSigma_A[7])                                   : .01         
(RIMSclockSigY_A[7])                                    : 0        

([8]RIMS_ID)                                            : "ABS"       
(refGain_A[8])                                          : 1           
(RIMSclockBias_A[8])                                    : 3417370.112
(RIMSclockDrift_A[8])                                   : -6442.29    
(RIMSclockSigma_A[8])                                   : .01         
(RIMSclockSigY_A[8])                                    : 0 

I can isolate the correct field in fileA with a combination of grep in a for loop and awk, but I don't know how I can replace the value in the file itself. Maybe I should use Perl but I don't have any experience. Any help would be appreciated.

Thank you!

a not so robust awk script

$ awk -v q='"' 'NR==FNR{a[q $1 q]=$2;next} 
                $3 in a{v=a[$3]; f=1} 
   /\(RIMSclockBias_A\[[0-9]+\]\)/ && f {sub($3,v); f=0}1' map file

([7]RIMS_ID)                                            : "CNR"
(refGain_A[7])                                          : 1
(RIMSclockBias_A[7])                                    : -44163754.49
(RIMSclockDrift_A[7])                                   : -6442.29
(RIMSclockSigma_A[7])                                   : .01
(RIMSclockSigY_A[7])                                    : 0

([8]RIMS_ID)                                            : "ABS"
(refGain_A[8])                                          : 1
(RIMSclockBias_A[8])                                    : 3417370.112
(RIMSclockDrift_A[8])                                   : -6442.29
(RIMSclockSigma_A[8])                                   : .01
(RIMSclockSigY_A[8])                                    : 0

where file is the data file and map is the lookup values. Assumes your structure is fixed (same number of fields, spacing and order of fields etc).

Slightly more readable, in my opinion:

BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" $1 "\""] = $2; next }
/RIMS_ID/ { key = $2; }
/RIMSclockBias_A/ { sub($2, bias[key]); }
{ print }

Now, if you wanted to limit substitution to a certain range of IDs, say 57 to 64, you could use something like this:

BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" $1 "\""] = $2; next }
/RIMS_ID/ { key = $2; }
/\[57\]RIMS_ID/ { substitute = 1 }
/\[65\]RIMS_ID/ { substitute = 0 }
/RIMSclockBias_A/ && substitute { sub($2, bias[key]); }
{ print }

So, as soon as ID 57 is encountered, we set substitute to true, and as soon as ID 65 is encountered, we set substitute to false, and we only carry out the substitution while that variable is true.

$ cat tst.awk
NR==FNR { map["\""$1"\""]=$2; next }
/^\(\[/ { key = $NF }
/^\(RIMSclockBias_A\[/ && key in map { sub(/[^[:space:]]+[[:space:]]*$/,map[key]) }
{ print }

$ awk -f tst.awk fileB fileA
([7]RIMS_ID)                                            : "CNR"
(refGain_A[7])                                          : 1
(RIMSclockBias_A[7])                                    : -44163754.49
(RIMSclockDrift_A[7])                                   : -6442.29
(RIMSclockSigma_A[7])                                   : .01
(RIMSclockSigY_A[7])                                    : 0

([8]RIMS_ID)                                            : "ABS"
(refGain_A[8])                                          : 1
(RIMSclockBias_A[8])                                    : 3417370.112
(RIMSclockDrift_A[8])                                   : -6442.29
(RIMSclockSigma_A[8])                                   : .01
(RIMSclockSigY_A[8])                                    : 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM