2017-02-27 62 views
1

字段的值可能的標題是不是一個很好的說明,但本質上,這是我試圖解決的問題:AWK:更換模式匹配字段與以前行

  • 我有一個文本文件與ñ行和空間分體字段在每一行中
  • 如果字段Ĵ行的一個模式匹配,與現場Ĵ行替換它我 - 1

我不是被迫使用AWK(GAWK在這個例子中),但它似乎是這個操作的一個不錯的選擇。這是我寫的,並預期它的工作sript,但我想知道是否有解決問題

{ 
    if ($0!~/NoData/) { 
     split($0, data, " "); 
     print $0 
    } else { 
     split($0, row, " ", seps); 
     for(i in row) {if (row[i]~/NoData/) row[i]=data[i]; else data[i]=row[i]; printf "%s%s", row[i], seps[i];} 
     printf "\n"                                    
    } 
} 

爲樣本,該腳本更加節省時間的方式,在此輸入文件運行

0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 NoData 0.0357 0.3922 0.0462 
0.6324 0.1576 NoData NoData 0.6555 0.0971 
0.0975 0.9706 NoData NoData 0.1712 0.8235 

應該產生這樣的結果

0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 0.8003 0.0357 0.3922 0.0462 
0.6324 0.1576 0.8003 0.0357 0.6555 0.0971 
0.0975 0.9706 0.8003 0.0357 0.1712 0.8235 

回答

2
awk '{for(i=1;i<=NF;i++){ if($i~/NoData/){ $i=last[i]; } last[i]=$i } }1' file 

如果你想保留原來的格式,你可以使用是低,如果你有gawksplit的第四個參數可能被利用。

awk '{ 
     split($0,D,/[^[:space:]]*/); 
     s = ""; 
     for(i=1;i<=NF;i++){ 
      if($i~/NoData/){ $i = last[i]; } 
      last[i]=$i ; 
      s = s sprintf("%s%s",D[i],$i) 
     } 
     print s 
}' file 

或通過設置OFS=""OFS=

awk -v OFS= '{ 
     split($0,D,/[^[:space:]]*/); 
     for(i=1;i<=NF;i++){ 
      if($i~/NoData/){ $i = last[i]; } 
      last[i]=$i ; 
      $i = sprintf("%s%s",D[i],$i) 
     } 
}1' file 

實施例 - 1(保留格式)

$ cat file 
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 NoData 0.0357 0.3922 0.0462 
0.6324 0.1576 NoData NoData 0.6555 0.0971 
0.0975 0.9706 NoData NoData 0.1712 0.8235 

$ awk '{ 
     split($0,D,/[^[:space:]]*/); 
     s = ""; 
     for(i=1;i<=NF;i++){ 
      if($i~/NoData/){ $i = last[i]; } 
      last[i]=$i ; 
      s = s sprintf("%s%s",D[i],$i) 
     } 
     print s 
}' file 
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 0.8003 0.0357 0.3922 0.0462 
0.6324 0.1576 0.8003 0.0357 0.6555 0.0971 
0.0975 0.9706 0.8003 0.0357 0.1712 0.8235 

實施例 - 2(不保留源格式)

默認情況下,它將單個空格作爲輸出分隔符,如果您設置了OFS,它將覆蓋默認值。

$ cat file 
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 NoData 0.0357 0.3922 0.0462 
0.6324 0.1576 NoData NoData 0.6555 0.0971 
0.0975 0.9706 NoData NoData 0.1712 0.8235 

$ awk '{for(i=1;i<=NF;i++){ if($i~/NoData/){ $i=last[i]; } last[i]=$i } }1' file 
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060 
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318 
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769 
0.9134 0.9649 0.8003 0.0357 0.3922 0.0462 
0.6324 0.1576 0.8003 0.0357 0.6555 0.0971 
0.0975 0.9706 0.8003 0.0357 0.1712 0.8235 
+0

哇,快和短。最後的結果是什麼? – Patrik

+0

@Patrik'1'默認操作'print $ 0'(打印當前行/記錄/行),意思是它的真實可以是任何非零數字 –

+1

好的,謝謝。我認爲保留格式不是優先事項,因爲輸出將被其他程序解析。沒關係,只要有至少一個空間 – Patrik