查找第二列中与第一列中的索引值相对应的最小数字

查找第二列中与第一列中的索引值相对应的最小数字

我有一些非常大的表,我需要提取特定的行。我用一个简单的例子来说明这个任务。假设,我称了一些苹果、香蕉和橙子的重量。我需要提取最小的苹果、香蕉和橙子的重量

原表:

Apple 3
Banana 8
Orange 2
Apple 7
Banana 9
Orange 13
Apple 9
Banana 1
Orange 11

期望的输出:

Apple 3
Banana 1
Orange 2

答案1

gnu datamash:

datamash -s -g 1 min 2 <infile
苹果3
香蕉 1
橙2

此操作按st 字段s进行排序和g分组,为第一个字段中的每个 ID 打印 nd 字段中的值。它假设字段由单个制表符分隔。如果它们由多个空格分隔或定义另一个字段分隔符(例如单个空格),则使用:1min2-W, --whitespace-t, --field-separator=

datamash -t' ' -s -g 1 min 2 <infile

由于datamash需要排序输入,因此输出也将按第一个字段排序。

答案2

awk

$ awk '($2<a[$1] || !a[$1]){a[$1]=$2}END{for(f in a){print f,a[f]}}' file
Orange 2
Banana 1
Apple 3

a[$1]=$2设置一个名为 的数组a,其键是第一个字段,其值是第二个字段。如果 i) 它小于存储的值或 ii) 没有存储值,上面的脚本会将第二个字段保存为数组中第一个字段的值。该END块迭代数组并打印其内容。


使用 GNU sort

$ sort -nk2 file |  sort -u -k1,1
Apple 3
Banana 1
Orange 2

第一种排序将以权重升序(第二个字段)打印行,第二种排序将仅保留唯一的行,但仅检查第一个字段。结果是打印每个字符串的第一次出现,由于第一次排序,该字符串将是该水果的最小值。


还有一个(稍微)短一点的 Perl:

$ perl -lane '$k{$F[0]}//=$F[1]; $k{$F[0]}=$F[1] if $F[1]<$k{$F[0]}; 
              END{print "$_ $k{$_}" for keys(%k)}' file 
Orange 2
Apple 3
Banana 1

//=除非变量已经有一个值,否则将分配一个值。然后,做法就和awk上面一样了。我们创建一个散列,%k其键是水果,其值是权重,并保存最小值。该-a标志的作用perl类似于awk将空格上的输入拆分到@F数组中。

答案3

您可以使用 perl oneliner 来完成此操作:

perl -ane '$h{$F[0]} = $F[1] if (!defined $h{$F[0]} || $h{$F[0]} > $F[1]); 
           END {foreach (keys %h) {print "$_ $h{$_}\n"}}' fruits_list.txt

这里我们使用哈希映射(%h)来存储元素。如果水果尚未存在于哈希中,我们将添加其第一个值,如果它已经存在,则仅当该值小于已存储的值时我们才更新该值。 END 块仅在处理文件的最后一行后执行,它打印哈希图。

答案4

sort -k2,2n file | sort -u -k1,1

输出:

苹果3
香蕉 1
橙2

相关内容