簡體   English   中英

bash / awk:獲取每個單元的最大值

[英]bash/awk: Getting largest value per cell

我有一個制表符分隔的fileA,看起來像這樣:

seqnameAa_len_240                     seqnameBa_len_247
seqnameAb_len_881                     seqnameBb_len_719
seqnameAc_len_736,seqnameAd_len_640   seqnameBc_len_489
seqnameAe_len_241                     seqnameBd_len_302,seqnameBe_len_465
seqnameAf_len_436,seqnameAf_len_620   seqnameBf_len_452,seqnameBg_len_435

左側的序列來自一個數據集,右側的序列來自另一個數據集。 每行反映一組相似序列。 在某些情況下,屬於同一序列組的一個,另一個或兩個數據集有一個以上的序列(由一列中用逗號表示的多個序列反映)。

對於每一行,我想找到一種為兩個數據集中的每個找到最大值的方法,並提供以下輸出。

240    247
881    719
736    489
241    465
620    452

我考慮過對所有行進行for循環,然后為每行用換行符替換逗號,然后刪除所有文本並僅保留數字,並用awk選擇每列的最大值。 但是,根據我目前的bash / awk知識,必須按列進行操作,並且每個單元格中沒有固定數量的逗號分隔條目,我不確定該怎么做。

有沒有更簡單的方法從fileA獲取以上輸出?

$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
    for (fldNr=1; fldNr<=NF; fldNr++) {
        split($fldNr,fldArr,/,/)
        for (sfNr=1; sfNr in fldArr; sfNr++) {
            sub(/.*_/,"",fldArr[sfNr])
            max = ( (sfNr==1)||(fldArr[sfNr]>max) ? fldArr[sfNr] : max)
        }
        $fldNr = max
    }
    print
}

$ awk -f tst.awk file
240     247
881     719
736     489
241     465
620     452
perl -MList::Util=max -lane '
    print max($F[0] =~ /\d+/g), "\t", max($F[1] =~ /\d+/g)
' fileA

我將使用一些gawk的技巧來實現此目的,而無需手動拆分:

gawk -F , -v RS='[\t\n]' '{ m = 0; for(i = 1; i <= NF; ++i) { sub(/.*_/, "", $i); if($i > m) { m = $i } } printf m RT }'

訣竅是使用制表符和換行符作為記錄分隔符,從而使記錄不再是行,而不再是行(例如seqnameAf_len_436,seqnameAf_len_620 ),並且字段$1$2等以逗號分隔。子字段(由於-F , )。 然后

{
  m = 0
  for(i = 1; i <= NF; ++i) { # walk through the (comma-delimited) fields 
    sub(/.*_/, "", $i)       # isolate the number
    if($i > m) {             # find the maximum
      m = $i
    }
  }
  printf m RT                # and print it with the same record terminator
                             # that was in the input (tab or newline)
}

使用正則表達式作為記錄分隔符和RT都是特定於gawk的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM