我有以下文件
...
MODE P E
IMP:P 1 19r 0
IMP:E 1 19r 0
...
SDEF POS= 0 0 14.6 AXS= 0 0 1 EXT=d3 RAD= d4 cell=23 ERG=d1 PAR=2
SI1 L 0.020
SP1 1
SI4 0. 3.401
SI3 0.9
...
NPS 20000000
我想做以下任务
ERG=
后是否有数字或字符串。SI1 L
并使用用户输入的值更改之后的值。请注意,如果在ERG=
之后有一个数字,则不会有SI1 L
个序列。
例如,数字2可以使用以下
来完成#! /bin/bash
vals=(0.02 0.03 0.04 0.05)
for val in "${vals[@]}"; do
awk -vval="$val" '$1=="SI1"{$3=val}1' 20
done
如何实现上述算法?
答案 0 :(得分:1)
awk -F '[[:blank:]=]' -v string_value="foo" -v number_value=42 '
/ERG=/ {
for (i=1; i<NF; i++)
if ($i == "ERG") {
isstring = ($(i+1) ~ /[^[:digit:]]/)
break
}
if (!isstring)
$(i+1) = number_value
}
/SI1 L/ && isstring { $NF = string_value }
1
' filename
答案 1 :(得分:1)
#!/bin/bash
val="$@"
awk -v val="$val" '
BEGIN { i=1; split (val,v," ") }
# If it is a string, find the sequence SI1 L and change the value after that, using values that the user inputs
/SDEF POS.*ERG=[a-zA-Z]+/ { flag="y" ; }
/SI1 L/ { if (flag=="y") { $3=v[i]; i++; flag="n"; } }
# If it is a number, change the number using values that the user inputs.
/SDEF POS.*ERG=[0-9]+ / { sub(/ERG=[0-9]*/, "ERG="v[i],$0);i++; }
1
' file
提示:
如果规则找到至少包含一个或多个字母的ERG([a-zA-Z] +,则会设置该标志。 如果设置了标志,则/ SI1 L /规则将仅触发。如果规则被触发,它将再次取消设置标志,以便任何后续/ SI L /不会再次触发。
。*代表0-n符号或字符
[A-Za-z] +代表小写或大写的1-n字母字符