2016-11-16 59 views
0

今天我正在糾正有幾個未知文件的文件中的數據錯誤。未知數是每個文件中字段的數量,以及哪些字段和記錄具有字符串「---」。帶斷點的AWK for循環

的數據的一個例子是:

1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 
4 4 2 39.6406 4 38.4964 --- 37.7414 --- 36.7149 
5 5 --- 40.2504 --- 39.0286 --- 38.4879 --- 38.1004 

所需的輸出是:

1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 
4 4 2 39.6406 4 38.4964 --- ---  --- --- 
5 5 --- ---  --- ---  --- ---  --- --- 

我已經使用for循環嘗試,如:

awk '{for (i = NF; i >= 1; i--){if ($i=="---")$(i-1)="---"}{print $0}}' file 

這導致在:

1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 
--- 
--- 

,我也試過:

awk '{for (i=1;i<=NF;i++){if ($i=="---")$(i+1)="---"}{print $0}}' file 

這就造成了錯誤:

"awk: program limit exceeded: maximum number of fields size=32767" 
    FILENAME="file" FNR=4 NR=4 
1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 

在我第一次嘗試,for循環千里迢迢到第一場,而在第二嘗試,具有所需字符串的記錄具有無限循環。

我的直覺是我需要應用一個break語句,但經過許多小時的搜索後,我找不到幫助我的例子。我知道還有一種方法可以讓貓變皮膚,所以如果你知道一個更好的方法來實現我的目標,請記住有多個文件具有不同的字段數,或者如果你可以提供一個break語句的例子我的一個for循環,我和其他人尋找一個例子,將非常感激。

謝謝

+1

一個問題,我看到的是你不在每次迭代中將索引遞增/遞減兩個並且重疊範圍。 – karakfa

回答

4

這應該工作

$ awk '{for(i=3;i<NF;i+=2) if($i=="---") $(i+1)=$i}1' file | 
    column -t 

1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 
4 4 2 39.6406 4 38.4964 --- ---  --- --- 
5 5 --- ---  --- ---  --- ---  --- --- 
+0

謝謝,我要添加到我的grimoire :-) –

2

所有你需要的是一個簡單的替換所以這是對sed的一份理想的工作:

$ sed -E 's/(-+ +)[^ ]+/\1\1 /g' file 
1 2 1 39.6406 1 38.8512 1 38.3479 1 37.9744 
2 1 4 39.1527 3 38.7329 2 38.3479 2 37.9744 
3 3 3 39.5186 2 38.8512 3 38.2079 3 37.6385 
4 4 2 39.6406 4 38.4964 --- ---  --- --- 
5 5 --- ---  --- ---  --- ---  --- ---