2012-03-18 5 views
1

私のデータは2列目が90、2列目が2列の値を変更しています。 11行目から9行目のカラム2の値を11から5に変更したいと思います。私は数値を変更したい値のセットを持っています。値は常に10,11,12,30,31,32から1,2,3,4,5,6になります。gawkを使用して特定の列を特定の値に置き換えます。

私のデータは

#  Type Response  Acc  RT  Offset  
    1  70 0 0 0.0000 57850 
    2  31 0 0 0.0000 59371 
    3  41 0 0 0.0000 60909 
    4  70 0 0 0.0000 61478 
    5  31 0 0 0.0000 62999 
    6  41 0 0 0.0000 64537 
    8  70 0 0 0.0000 65106 
    9  11 0 0 0.0000 66627 
    10  21 0 0 0.0000 68165 
    11  90 0 0 0.0000 68700 
    12  31 0 0 0.0000 70221 

私は

#  Type Response  Acc  RT  Offset  
    1  70 0 0 0.0000 57850 
    2  31 0 0 0.0000 59371 
    3  41 0 0 0.0000 60909 
    4  70 0 0 0.0000 61478 
    5  31 0 0 0.0000 62999 
    6  41 0 0 0.0000 64537 
    8  70 0 0 0.0000 65106 
    9  5 0 0 0.0000 66627 
    10  21 0 0 0.0000 68165 
    11  90 0 0 0.0000 68700 
    12  31 0 0 0.0000 70221 

たい私は前の行を保存し、参照としてそれを使用しようとしているが、私は唯一のバック一行を行くことができる、と私は必要2つ戻る。ご協力ありがとうございました。

+0

'1,2,3,4,5にあなたの翻訳・シーケンス' 10,11,12,30,31,32'、 「6」はあなたの「11」から「5」への変更要求と一致しません –

答えて

1

これは動作するはずです:

function pra(a) { 
    for(e in a) { 
    printf "%s ", a[e]; 
    } 
    print ""; 
} 
BEGIN { 
    vals[10] = 1; 
    vals[11] = 2; 
    vals[12] = 3; 
    vals[30] = 4; 
    vals[31] = 5; 
    vals[32] = 6; 
} 
NR == 1 { split($0, a, " ") } 
NR == 2 { split($0, b, " ") } 
NR > 2 { 
    if($2 == "90") { 
    a[2] = vals[a[2]]; 
    } 
    pra(a); 
    al = 0; 
    for(i in a) al++; 
    for(i = 1; i <= al; i++) { 
    a[i] = b[i]; 
    } 
    split($0, b, " "); 
} 
END { 
    pra(a); 
    pra(b); 
} 

これがどのように動作するかの荒廃: * BEGINGブロックを - NR == 1とNR == 2 * vals に翻訳値を割り当てる - 最初の2行を覚えています*最初の二つ 後のすべての行のための第二の列は値90がある場合、aにアレイbの翻訳配列 *移動要素を使用して変更し、Cを分割 - 分割アレイab * NR> 2へ作るために

function pra(a) { 
    printf "%4d%8d%3d%5d%9.4f%6d\n", a[1], a[2], a[3], a[4], a[5], a[6] 
} 
BEGIN { 
    vals[10] = 1; 
    vals[11] = 2; 
    vals[12] = 3; 
    vals[30] = 4; 
    vals[31] = 5; 
    vals[32] = 6; 
} 
NR == 1 { print } 
NR == 2 { split($0, a, " ") } 
NR == 3 { split($0, b, " ") } 
NR > 4 { 
    if($2 == "90") { 
    a[2] = vals[a[2]]; 
    } 
    pra(a); 
    for(i = 1; i <= 6; i++) { 
    a[i] = b[i]; 
    } 
    split($0, b, " "); 
} 
END { 
    pra(a); 
    pra(b); 
} 

$ cat inp && awk -f mkt.awk inp 
#  Type Response  Acc  RT  Offset  
    1  70 0 0 0.0000 57850 
    2  31 0 0 0.0000 59371 
    3  41 0 0 0.0000 60909 
    4  70 0 0 0.0000 61478 
    5  31 0 0 0.0000 62999 
    6  41 0 0 0.0000 64537 
    8  70 0 0 0.0000 65106 
    9  11 0 0 0.0000 66627 
    10  21 0 0 0.0000 68165 
    11  90 0 0 0.0000 68700 
    12  31 0 0 0.0000 70221 

# Type Response Acc RT Offset 
1 70 0 0 0.0000 57850 
2 31 0 0 0.0000 59371 
3 41 0 0 0.0000 60909 
4 70 0 0 0.0000 61478 
5 31 0 0 0.0000 62999 
6 41 0 0 0.0000 64537 
8 70 0 0 0.0000 65106 
9 2 0 0 0.0000 66627 
10 21 0 0 0.0000 68165 
11 90 0 0 0.0000 68700 
12 31 0 0 0.0000 70221 

あなたはこのような何かを行うことができます。基本的にプリントab、最後の2行

サンプル実行 - b * ENDブロックにurrentラインこれは、書式設定を含むこの特定のケースで機能します。サンプルの実行:

$ cat inp && awk -f mkt.awk inp 
#  Type Response  Acc  RT  Offset  
    1  70 0 0 0.0000 57850 
    2  31 0 0 0.0000 59371 
    3  41 0 0 0.0000 60909 
    4  70 0 0 0.0000 61478 
    5  31 0 0 0.0000 62999 
    6  41 0 0 0.0000 64537 
    8  70 0 0 0.0000 65106 
    9  11 0 0 0.0000 66627 
    10  21 0 0 0.0000 68165 
    11  90 0 0 0.0000 68700 
    12  31 0 0 0.0000 70221 
#  Type Response  Acc  RT  Offset  
    1  70 0 0 0.0000 57850 
    2  31 0 0 0.0000 59371 
    4  70 0 0 0.0000 61478 
    5  31 0 0 0.0000 62999 
    6  41 0 0 0.0000 64537 
    8  70 0 0 0.0000 65106 
    9  2 0 0 0.0000 66627 
    10  21 0 0 0.0000 68165 
    11  90 0 0 0.0000 68700 
    12  31 0 0 0.0000 70221 
+0

あまりにも早く返信いただきありがとうございます。私はあなたのコードを試しました、私は上記のようにデータの書式を維持することは可能ですか?あなたのコードを実行すると、データとヘッダが再配置された出力が得られました(Acc RT Offset#Type Response 0 0.0000 43991 1 55 0)。また、どのようにコードが実行されているかの内訳を教えてもらえますか?また、ありがとうございます、それはほとんどの部分で動作しました。 – user1269741

+0

ありがとうございました - 編集を参照して、あなたに何かを働かせることを望みます。 –

+0

注:問題のフィールドがリスト'10,11,12,30,31,32'の**ではなく**である場合、それは悪い置換を行います...それは何の番号も '0'で置き換えられます。リストには唯一可能な値が含まれていることを意味するのかどうかはわかりません(他の値がある場合は言及する価値があります)。 –

0

このバージョンでは、あなたの元の書式を維持し

awk 'BEGIN{ new[" 1"]="10"; new[" 2"]="11"; new[" 3"]="12" 
      new[" 4"]="30"; new[" 5"]="31"; new[" 6"]="32" } 
    { line[-2]=line[-1]; line[-1]=line[0]; line[0]=$0 } 
    $2==90 { if(match(line[-2], /^ *[0-9]+ +[1-6] /)) { 
        old=substr(line[-2], RLENGTH-2,2) 
        line[-2]=substr(line[-2], 1, RLENGTH-3) new[old] \ 
          substr(line[-2], RLENGTH) } } 
    NR>2 { printf("%s\n",line[-2]) } 
    END { printf("%s\n%s\n",line[-1],line[0]) }' file.in 
関連する問題