Linux:用其他文件中的值替换文本字段
Linux: Substitute text fields with values from other file
好的,我不知道该怎么做。
我有一个如下所示的 FileA :
([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
依此类推,其中 [index] 从 0 到 71,每个站点都有不同的 ID。
我想用我在另一个文件 B 上的值替换每个站的 RIMSclockBias_A 字符串对应的值,如下所示:
CNR -44163754.49
ABS 3417370.112
...
所以有:
([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
我可以通过 for 循环中的 grep 和 awk 的组合来隔离 fileA 中的正确字段,但我不知道如何替换文件本身中的值。
也许我应该使用 Perl,但我没有任何经验。
任何帮助将不胜感激。
谢谢!
一个不太健壮的awk
脚本
$ awk -v q='"' 'NR==FNR{a[q q]=;next}
in a{v=a[]; f=1}
/\(RIMSclockBias_A\[[0-9]+\]\)/ && f {sub(,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
其中 file 是数据文件,map 是查找值。假设您的结构是固定的(相同的字段数、间距和字段顺序等)。
$ cat tst.awk
NR==FNR { map["\"""\""]=; 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
我认为更具可读性:
BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" "\""] = ; next }
/RIMS_ID/ { key = ; }
/RIMSclockBias_A/ { sub(, bias[key]); }
{ print }
现在,如果你想将替换限制在特定范围内的 ID,比如 57 到 64,你可以使用这样的东西:
BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" "\""] = ; next }
/RIMS_ID/ { key = ; }
/\[57\]RIMS_ID/ { substitute = 1 }
/\[65\]RIMS_ID/ { substitute = 0 }
/RIMSclockBias_A/ && substitute { sub(, bias[key]); }
{ print }
所以,一遇到ID 57,我们就设置substitute
为true,一遇到ID 65,我们就设置substitute
为false,我们只执行当该变量为真时进行替换。
好的,我不知道该怎么做。
我有一个如下所示的 FileA :
([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
依此类推,其中 [index] 从 0 到 71,每个站点都有不同的 ID。
我想用我在另一个文件 B 上的值替换每个站的 RIMSclockBias_A 字符串对应的值,如下所示:
CNR -44163754.49
ABS 3417370.112
...
所以有:
([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
我可以通过 for 循环中的 grep 和 awk 的组合来隔离 fileA 中的正确字段,但我不知道如何替换文件本身中的值。 也许我应该使用 Perl,但我没有任何经验。 任何帮助将不胜感激。
谢谢!
一个不太健壮的awk
脚本
$ awk -v q='"' 'NR==FNR{a[q q]=;next}
in a{v=a[]; f=1}
/\(RIMSclockBias_A\[[0-9]+\]\)/ && f {sub(,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
其中 file 是数据文件,map 是查找值。假设您的结构是固定的(相同的字段数、间距和字段顺序等)。
$ cat tst.awk
NR==FNR { map["\"""\""]=; 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
我认为更具可读性:
BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" "\""] = ; next }
/RIMS_ID/ { key = ; }
/RIMSclockBias_A/ { sub(, bias[key]); }
{ print }
现在,如果你想将替换限制在特定范围内的 ID,比如 57 到 64,你可以使用这样的东西:
BEGIN { FS = " *:? *" }
NR == FNR { bias["\"" "\""] = ; next }
/RIMS_ID/ { key = ; }
/\[57\]RIMS_ID/ { substitute = 1 }
/\[65\]RIMS_ID/ { substitute = 0 }
/RIMSclockBias_A/ && substitute { sub(, bias[key]); }
{ print }
所以,一遇到ID 57,我们就设置substitute
为true,一遇到ID 65,我们就设置substitute
为false,我们只执行当该变量为真时进行替换。