如何有条件地过滤awk中的行

时间:2018-02-16 18:13:20

标签: awk

我是linux新手。我有一个1700万行的大文本文件。第一列是ID,第二列是Age。每个主题可能有多个年龄,我只想过滤每个主题的最小年龄,并将它们打印在单独的文本文件中。我不确定受试者是否从低到高排在第一列......这是前几行:

ID          Age
16214497  36.000
16214497  63.000
16214727  63.000
16214781  71.000
16214781  79.000
16214792  67.000
16214860  79.000
16214862  62.000
16214874  61.000

3 个答案:

答案 0 :(得分:2)

如果文件未排序,则需要将记录保存在内存中以查找最小值。如果你需要排序,这可能会更好

$ sed 1d file         |   # remove header
  sort -k1,1 -k2n     |   # sort by ID, then by age, numerically
  uniq -w8            |   # find the first unique record by ID only
  sed '1iID  Min_Age' |   # insert back the new header
  column -t               # pretty print

ID        Min_Age
16214497  36.000
16214727  63.000
16214781  71.000
16214792  67.000
16214860  79.000
16214862  62.000
16214874  61.000

答案 1 :(得分:1)

尝试(只是没有管道的awk,使用内存来保留值):

$ awk '
    NR=1{print; next}                     # ¹
    arr[$1]==0 {arr[$1]=$2}               # ²
    ($2 < arr[$1]) {arr[$1]=$2}           # ³
    END{for (i in arr) {print i, arr[i]}} # ⁴
' file

真正的命令行:

(如果多行让你害怕)

awk 'NR=1{print; next} arr[$1]==0 {arr[$1]=$2} ($2 < arr[$1]) {arr[$1]=$2} END{for (i in arr) {print i, arr[i]}}' x.txt

(但也适用于换行符和评论,up2u)

评论:

  • ¹打印,然后跳过第1行
  • ²如果arr [key]的值为null,则我们向第2列提供arr [key],动态创建数组 (第一列为键)。
  • ³如果第二列小于arr [key],则将第二列的新值分配给arr [key]
  • ⁴@处理所有行的结束,我们打印数组的键和值

输出:

ID          Age
16214497 36.000
16214727 63.000
16214781 71.000
16214792 67.000
16214860 79.000
16214862 62.000
16214874 61.000

答案 2 :(得分:-2)

$ tail +2 file | sort | awk '!seen[$1]++'
16214497  36.000
16214727  63.000
16214781  71.000
16214792  67.000
16214860  79.000
16214862  62.000
16214874  61.000