2017-10-13 129 views
0

我們有一個固定的寬度文件如何讀取逗號分隔值

Col1 length 10 
Col2 length 10 
Col3 length 30 
Col4 length 40 

樣品記錄

ABC  123  xyz.       5171-5261,51617 
ABC.   1234.  Xxy.  81651-61761 

COL4可以具有任何數量的逗號分隔值 1或40個字符長度內多個:
如果該記錄有1個值,則輸出文件沒有變化。 如果有多個值,即逗號分隔(5171-5261,51617) 輸出文件應該有多個記錄。

1 record 
ABC. 123. Xyz. 5171-5261 
ABC  123. Xyz. 51617 

什麼是最有效的方法來做到這一點。 截至目前試圖使用while和for循環,但它需要很長時間才能執行,因爲我們通過讀取每條記錄來進行分割。

輸出文件可以用逗號分隔或固定寬度。

+0

一個很好的問題會包含一小組樣本數據,該輸入的預期輸出,當前代碼/輸出/錯誤消息以及您爲什麼不工作的想法。請閱讀https://stackoverflow.com/help/on-topic,http://stackoverflow.com/help/how-to-ask,http://stackoverflow.com/help/dont-ask,http:// stackoverflow.com/help/mcve,也許是http://stackoverflow.com/tour。祝你好運。 – shellter

回答

1

awk是你的朋友在這裏。

的awk單行將實現你需要的東西:

awk -v FIELDWIDTHS="10 10 30 40" '{ if (match($4,",")) { split($4,array,","); for (i in array) { print $1,$2,$3,array[i]; }; } else { print $1,$2,$3,$4 }; }' samp.dat 

爲了便於閱讀代碼是:

{ 
    if (match($4,",")) { 
     split($4,array,","); 
     for (i in array) { 
      print $1,$2,$3,array[i]; 
     }; 
    } else { 
     print $1,$2,$3,$4 
    }; 
} 

測試您所提供的樣本數據得出:

ABC  123  xyz.       5171-5261 
ABC  123  xyz.       51617 
ABC.   1234.  Xxy.  81651-61761 


工作原理:
awk一次讀取一行文件。
FIELDWIDTHS指令允許我們引用每列作爲$1,$2...
現在我們有我們的列,我們可以在match($4,",")的第四個字段中查找逗號。
如果我們找到一個,我們在第四個字段中創建一個由逗號分隔的值的數組,其中split($4,array,",")
然後我們遍歷這個數組並打印多行輸出,每個元素對應一個數組。
如果第四個字段沒有逗號,則else子句將打印一行。
對於固定寬度文件中的每一行重複此過程。

注意: awk關聯arrays不保證保留您的數據的順序。 這意味着您的輸出可能出來作爲

ABC  123  xyz.       51617 
ABC  123  xyz.       5171-5261 
ABC.   1234.  Xxy.  81651-61761 
在輸入數據

5171-5261,51617產生之前從所述第一第二值的線。

如果排序對您很重要,那麼您可以使用下面的代碼先從輸入數據中生成一個csv,然後生成輸出以保存順序。

awk -v FIELDWIDTHS="10 10 30 40" '{print $1,$2,$3,$4}' OFS=',' samp.data > samp.csv 
awk -F',' '{ for (i=4; i<=NF; i++) { print $1,$2,$3,$i } }' samp.csv 
+1

而且我知道如何花費大量的時間回答問題並獲得反饋,令人沮喪;-)。很好的答案。繼續發帖。 – shellter