我有一个包含大量不同文本的大文件。我想使用一个脚本来遍历整个文件并将数字乘以预定数量,在本例中为 EXP="XYZ" 数字字段中的 2。然而,只有当 VIEW_RANGE、COOLEYE 和 TAMEBLE 位于其前面时,它才必须执行此操作。整个文件也是一个完整的衬里。
例子
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="12000"
TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="1000"
最终应该看起来像
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="24000"
TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="2000"
我怎样才能实现这个目标?
答案1
让我们考虑这个测试文件:
$ cat file
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="12000" other stuff EXP="2" TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="1000"
要使 EXP 值加倍,但前提是前面有 TAMEBLE、COOLEYE 和 VIEW_RANGE:
$ awk -F'[="]+' '$1=="TAMEBLE" {a[NR]=1} $1=="COOLEYE"{b[NR]=1} $1=="VIEW_RANGE" {c[NR]=1} $1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {$0= $1 "=\"" (2*$2) "\""} END{printf"\n"} 1' RS=' ' ORS=' ' file
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="24000" other stuff EXP="2" TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="2000"
或者,如果您更喜欢将代码分布在多行中:
awk -F'[="]+' '
$1=="TAMEBLE" {
a[NR]=1
}
$1=="COOLEYE"{
b[NR]=1
}
$1=="VIEW_RANGE" {
c[NR]=1
}
$1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {
$0= $1 "=\"" (2*$2) "\""
}
END{printf"\n"}
1
' RS=' ' ORS=' ' file
怎么运行的
-F'[="]+'
这将字段分隔符设置为
=
或的任意组合"
。$1=="TAMEBLE" {a[NR]=1}
如果该记录的第一个字段是 TAMEBLE,则设置
a[NR]
为 true,其中NR
是记录编号。$1=="COOLEYE"{b[NR]=1}
同样,如果该记录的第一个字段是 COOLEYE,则设置
b[NR]
为 true。$1=="VIEW_RANGE" {c[NR]=1}
同样,如果该记录的第一个字段是 VIEW_RANGE,则将
c[NR]` 设置为 true。
$1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {$0= $1 "=\"" (2*$2) "\""}
如果该记录的第一个字段为
EXP
且先前记录的第一个字段符合要求的顺序,则将 的值加倍EXP
。END{printf"\n"}
读完文件后,打印一个换行符以正确结束该行。
1
这是 awk 的 print-the-line 的神秘简写。
RS=' ' ORS=' '
这告诉 awk 将空白视为输入和输出上的记录分隔符。