2016-10-20 83 views
0

獲得具有非零值的列/字段的任何更好的想法。AWK獲取非零值的列

數據

 col1 col2 col3 .... col50 
     1  0 1   1 

所以輸出應該是

col1 col3 .... col50 
    1  1   1 

編輯:實施例是錯誤的,所以編輯它。

+0

你嘗試過什麼?您將需要讀取所有數據,並檢查除列標題行以外每行中每列的所有值是否包含至少一個非零值。直到讀完所有數據行,才能開始打印標題行以外的任何內容。這對Awk來說是一個問題。 –

+0

喬納森,實際上我的例子是錯的,現在編輯它。感謝您指出它。 –

+0

輸入文件是否真的只有兩行,一個標題行和一個數據行?或者你是否需要打印除第一行之外的每一行的非零元素?或者是否需要爲每行打印相關標題和相關列(因此輸出行1作爲標題的子集,行2作爲行1的非零數據,行3作爲標題的子集,第4行作爲第2行中的非零數據,等等)?或者是什麼?如果它比最初似乎更簡單,那麼你又試過了什麼?但你確實需要更清楚地解釋輸入和輸出。 –

回答

1

awk來救援!

這應該處理多行以及...

$ awk 'NR==1{split($0,h); next} 
    NR==FNR{for(i=1; i<=NF; i++) if($i!=0) cols[i]; next}    
      {for(i=1; i<=NF; i++) if(i in cols) printf "%s", $i OFS; 
      print ""}' file{,} | column -t 

col1 col3 col50 
1  1  1 
1

在awk中,多個記錄的更通用的解決方案。在第一次去它會檢查以1s的cols,它輸出的記錄用ls第二:

$ cat program.awk 
NR>1 && NR==FNR {        # find columns to output, build a arr on 1 
    for(i=1;i<=NF;i++) 
     if($i) a[i] 
    next 
} 
sub(/1/,"1") {        # output only records with 1s 
    split($0,b," ")       # split record to b arr 
    for(i=1;i<=NF;i++) 
    if(i in a)        # print on a arr 
     printf "%s%s", b[i], (i==NF?ORS:OFS) 
} 

數據:

$ cat data.txt 
col1 col2 col3 col4 
0 0 0 0 
1 0 1 0 
0 0 1 1 

運行:

$ awk -f program.awk data.txt data.txt 
col1 col3 col4 
1 1 0 
0 1 1