正規表現に一致する同じ行の2つの文字列を変更する

正規表現に一致する同じ行の2つの文字列を変更する

.datファイルには、スクリプトを使用して自動的に変更した多くの変数があります。これらのファイルの1つには、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すべてbar2000です。

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

代わりに2000fooに変更され、bar変更されていません。これは正規表現を記述する方法に問題があることを知っていますが、awk / sed式を使用してこれら2つの変数を変更することはできません。

ベストアンサー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

おすすめ記事