2016-07-04 61 views
0

在下面的文件:切割成多個字段的第一個字段文件

position1 456754 0/1:170,167:339:99:3370,0,3372:50:99:0.496 ./.:.:.:.:.:.:.:. 
position2 456759 0/1:161,162:325:99:3266,0,3215:50:99:0.502 ./.:.:.:.:.:.:.:. 

我想要得到的輸出:

position1 456754 0/1 ./. 
position2 456759 0/1 ./. 

這是第三和第四場,我想獲取包含/

第一場如果只有一列,我可以做到以下幾點:

cut -d " " -f3 - | cut -f1 -d ":" 

粘貼前兩個欄後,這將只給我:

position1 456754 0/1 
position2 456759 0/1 

我的文件總共有200列,如何延長這一對文件中的所有領域?

回答

1

您可以製作一個awk單行程序,用於拆分包含冒號的字段,並僅用一個子字段替換那些空白分隔的字段。類似這樣的:

$ cat inp.txt 
position1 456754 0/1:170,167:339:99:3370,0,3372:50:99:0.496 ./.:.:.:.:.:.:.:. 
position2 456759 0/1:161,162:325:99:3266,0,3215:50:99:0.502 ./.:.:.:.:.:.:.:. 
$ awk '{ for(i=1; i<=NF; i++) { if($i~/:/){split($i,a,":"); $i=a[1] } } } 1' inp.txt 
position1 456754 0/1 ./. 
position2 456759 0/1 ./. 

for循環遍歷字段列表。然後,如果有任何字段包含冒號,我們將該字段放入一個數組(a),並用第一個元素(a[1])替換整個字段($i)。命令字符串末尾的1對於「打印此行」是短暫的,無論是否進行了任何替換,這都會發生。

如果你想在某個CPU爲代價的一個簡單的awk腳本,這也應該工作:

$ awk '{ for(i=1; i<=NF; i++) { split($i,a,":"); $i=a[1] } } 1' inp.txt 

這只是消除了if()條件,這樣對每行每一個領域,你將取代領域與「第一個冒號定界的子領域」。對於沒有冒號的字段,這會將字段替換爲它自己。

或者,對於穩健的解決方案少,你可以使用sed

$ sed -r -e 's/(:[^ ]*)(|$)/\2/g' inp.txt 
position1 456754 0/1 ./. 
position2 456759 0/1 ./. 

該解決方案的行內讀取和替代字符串,而不是解析領域的awk在做事情的方式。它可能和awk解決方案一樣可靠,雖然可能稍微不靈活(例如awk會讓你採用不同的子域,而sed解決方案則不然)。

注意替換命令結束時的g。這告訴sed執行「全局」替代,而不僅僅是搜索正則表達式的第一個匹配。

此解決方案使用-r選項告訴sed使用擴展正則表達式。如果您使用的是OS X或某些(較早)的BSD unix版本,請使用-E選項。在其他情況下,您可能必須將其轉換爲BRE。

只是兩種方法。我相信在其他答案中會出現更多。

相關問題