首頁  >  問答  >  主體

linux - shell 排序去重问题

用 shell 处理一个文本文件,内容如下:

fdf     284 
asd     112
adf     146
csb     513
dfg     576
asd     346
adf     263
csb     092
dfg     547

根据第一列去重,相同的保留第二列值最大的那个,结果数据应该是这样的:

fdf    284
asd    346
adf    263
csb    513
dfg    576

看了下 uniq 命令,好像不支持按字段去重。请问该如何去重呢?

PHPzPHPz2743 天前829

全部回覆(4)我來回復

  • 阿神

    阿神2017-04-17 11:54:44

    方法一

    cat data.txt | sort -rnk2 | awk '{if (!keys[]) print 
    cat data.txt | sort -k1,1 | awk '{
        if (lastKey == ) {
            if (lastValue < ) {
                lastLine = rrreee;
                lastValue = int();
            }
        } else {
            if (lastLine) {
                print lastLine;
            }
    
            lastKey = ;
            lastLine = rrreee;
            lastValue = int();
        }
    } END {
        if (lastLine) {
            print lastLine;
        }
    }'
    
    ; keys[] = 1;}'

    先按照第二列逆序排列,確保數字從大到小輸出,然後再用awk,只有第一列的字串第一次出現才輸出這個字串,其他的丟棄,這樣應該就可以解決問題了。但是這種方法可能會讓 awk 佔用很多的內存,文件過大的話有問題。

    方法二

    rrreee

    這個方案是依照第一列排序,然後用 awk 篩選結果,篩選的過程相當於一個加強版的 uniq。這個方案在記憶體使用上好了很多,不過程式碼量略多,不是很簡潔。

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:54:44

    $ sort -r a.txt | awk '{print , }' | uniq -f1 | awk '{print , }'
    fdf 284
    dfg 576
    csb 513
    asd 346
    adf 263
    

    逆排, 反轉第一列和第二列, 按第二列去重, 反轉第一列和第二列

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:54:44

    awk  'BEGIN{ a[]= }{ if (>a[] )  a[]=  }END{for (i in a) if (i)  print i,a[i]}' data.txt   
    

    把第一列放入數組 然後對比數組的值 大的就替換掉為新的值

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 11:54:44

    雷雷

    回覆
    0
  • 取消回覆