2012-03-18 90 views
1

我試圖在任何地方找到我的數據在列2中有一個90,上面兩行改變了列2的值。例如,在我的數據下面,如果我看到90第11行我想將第2行的第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 

我一直在嘗試存儲前行,並把它作爲一個參考,但我只能回去一條線是什麼,我需要回去兩次。感謝您的幫助。

+0

你的翻譯序列'10,11,12,30,31,32'到'1,2,3,4,5, 6'不符合您的要求將「11」更改爲'5' – 2012-03-18 03:43:52

回答

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塊 - 分配翻譯值vals * NR == 1和NR == 2 - 還記得前兩行成分割陣列ab * NR> 2 - 對於所有行後的頭兩個 *如果第二列具有值90,使用翻譯陣列 *移動陣列b的元素a改變它和分裂的C urrent行成b * END塊 - 打印ab,它們基本上是最後兩行

採樣運行:

$ 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 

你可以做這樣的事情:

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 
    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 2012-03-18 03:07:46

+0

謝謝 - 看看編輯,希望能給你一些工作。 – 2012-03-18 03:27:39

+0

注意:當列表中的字段是** not **時,它會導致錯誤的替換'10,11,12,30,31,32'...它會用'0'替換那裏的數字。他提到給出的列表有確切的替代,但我不確定他是否意味着列表包含唯一可能的值......(值得一提的是,如果可以有其他值)。 – 2012-03-18 07:51:30

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