2013-04-08 91 views
0

我正在學習AWK,並試圖對內置字符串函數進行一些練習。awk命令拆分第n個字段

這裏是我的鍛鍊:

我有一個包含如下

RecordType:83  
1,2,3,a|x|y|z,4,5 

而我需要的輸出文件是如下:

RecordType:83  
1,2,3,a,4,5   
1,0,0,x,4,5   
1,0,0,y,4,5  
1,0,0,z,4,5 

我寫了一個awk命令用於上述輸出。

awk -F',' '$1 ~ /RecordType:83/{print $0} 

$1 == 1{ 

split($4,splt,"|") 

for(i in splt) 

{ 

if(i==1) 

print $1,$2,$3,splt[i],$5,$6 

else 

print $1,0,0,splt[i],$5,$6 

} 

}' OFS=, file_name 

上面的命令看起來很笨拙。有什麼辦法來最小化命令?

在此先感謝

回答

3

最短的一個班輪我可以管理:

awk -F, 'NR>1{n=split($4,a,"|");for(;i++<n;){$4=a[i];print;$2=$3=0}}NR==1' OFS=, file 
RecordType:83     
1,2,3,a,4,5 
1,0,0,x,4,5 
1,0,0,y,4,5 
1,0,0,z,4,5 

更多可讀的腳本(推薦)

BEGIN { 
    FS=OFS=","          # Comma delimiter 
} 
NR==1 {            # If the first line in file 
    print $0           # Print the whole line 
    next            # Skip to next line 
} 
{ 
    n=split($4,a,"|")        # Split field four on | 
    for(i=1;i<=n;i++)        # For each sub-field 
     print $1,i==1?$2OFS$3:"0"OFS"0",a[i],$5,$6 # Print the output 
} 
+0

AWK -F,「NR> 1 {分裂($ 4, 「|」);對於(i的一個)$ 4 = A [1];打印; $ 2 = $ 3 = 0}} NR == 1'OFS =,文件 – kattashri 2013-04-09 05:52:59

+0

我剛剛修改了上面的命令以適用於多行 – kattashri 2013-04-09 05:55:28

+0

您最好使用傳統的for循環,以保證順序。 – 2013-04-09 07:44:43

1

另一個短單班輪

awk -F, -v OFS="," 'NR>1{n=split($4,a,"|");while(++i<=n){$4=a[i];print;$2=$3=0}}NR==1' file 

與例如:

kent$ awk -F, -v OFS="," 'NR>1{n=split($4,a,"|");while(++i<=n){$4=a[i];print;$2=$3=0}}NR==1' file                   
RecordType:83  
1,2,3,a,4,5 
1,0,0,x,4,5 
1,0,0,y,4,5 
1,0,0,z,4,5 
+0

嗨肯特,感謝您的更好的答案,但如果我們認爲在下一個級別。該命令僅適用於單個逗號分隔的行。 – kattashri 2013-04-09 05:45:38

+0

添加到上面的評論我認爲我們需要改變循環計數 – kattashri 2013-04-09 05:48:05

+3

@kattashri如果你有更多的逗號分隔的行,你必須在循環後重置'i'。它看起來'awk -F,-v OFS =「,''NR> 1 {n = split($ 4,a,」|「); while(++ i <= n){$ 4 = a [i]; print ; $ 2 = $ 3 = 0;} i = 0} NR == 1'file'你的'for(i in a)'不安全。因爲'我在'不能保證訂單。 – Kent 2013-04-09 06:55:01