我在 .dat 文件中有许多变量,我使用脚本自动更改了这些变量。这些文件之一有一个参数 ,bar
在 .dat 文件中按如下方式排列:
var1 var2 var3 foo bar
T T T 100 100
我曾经使用 bash 脚本的以下几行将 bar 的值从任意初始值更改为所需值,在本例中为 2000。该脚本会将“bar”更改为 2000。
LINE1=$(awk '/bar/ {++n;if (n==1) {print FNR}}' data.dat)
((LINE1=$LINE1 + 1))
OLD1=$(awk '{for(i=1;i<'$LINE1';i++) getline}{print $12}' data.dat)
sed -i '' "${LINE1}s/$OLD1/2000/" data.dat
然而,我现在必须和……foo
一起改变bar
。在此示例中,此设置foo
均为bar
2000。
LINE1=$(awk '/foo/ {++n;if (n==1) {print FNR}}' data.dat)
((LINE1=$LINE1 + 1))
OLD1=$(awk '{for(i=1;i<'$LINE1';i++) getline}{print $12}' data.dat)
sed -i '' "${LINE1}s/$OLD1/2000/" data.dat
LINE1=$(awk '/bar/ {++n;if (n==1) {print FNR}}' data.dat)
((LINE1=$LINE1 + 1))
OLD1=$(awk '{for(i=1;i<'$LINE1';i++) getline}{print $12}' data.dat)
sed -i '' "${LINE1}s/$OLD1/2000/" data.dat
相反,这仅将 更改foo
为 2000,而保持bar
不变。我意识到这是我描述正则表达式的方式的问题,但我无法使用 awk/sed 表达式更改这两个变量。
答案1
你可以做
awk -v newvalue=2000 '
NR == 1 {
for (i=1; i<=NF; i++) {
if ($i == "foo") i_foo=i
if ($i == "bar") i_bar=i
}
}
NR == 2 {$i_foo = $i_bar = newvalue}
{print}
' file.dat | column -t
var1 var2 var3 foo bar
T T T 2000 2000
或者,减少 awk 中的硬编码
awk -v cols="var2=1234,bar=5678" '
BEGIN {
n = split(cols, a, /[=,]/)
for (i=1; i<n; i+=2) newval[a[i]] = a[i+1]
}
NR == 1 { for (i=1; i<=NF; i++) if ($i in newval) idx[$i] = i }
NR == 2 { for (col in idx) $(idx[col]) = newval[col] }
{print}
' file.dat | column -t
var1 var2 var3 foo bar
T 1234 T 100 5678
答案2
只是为了好玩:
awk -F'\t' -vOFS='\t' -vfoovalue=2101 -vbarvalue=2102 '
/foo/&&/bar/{
row=NR
for(i=1;i<=NF;i++){
if($i=="foo"){colfoo=i}
if($i=="bar"){colbar=i}
}
print
}
NR==row+1{ $colfoo=foovalue; $colbar=barvalue; print }
' file
var1 var2 var3 foo bar
T T T 2101 2102