I have some very large tables and I need to extract specific rows. I am illustrating the task using a simple example. Say, I have weighed a number of apples, bananas and oranges. I need to extract the weight of the smallest apple, banana and orangeOriginal table:Apple 3Banana 8Orange 2Apple 7Banana 9Orange 13Apple 9Banana 1Orange 11Desired output:Apple 3Banana 1Orange 2
Find the smallest numbers in the second column corresponding to index values in first column
command line;text processing;sed;awk
With awk:$ awk '($2<a[$1] || !a[$1]){a[$1]=$2}END{for(f in a){print f,a[f]}}' fileOrange 2Banana 1Apple 3a[$1]=$2 sets up an array called a, whose keys are the 1st field and whose value is the second. The script above will save the second field as the value for the first in the array if i) it is smaller than the value stored or ii) there is no value stored. The END block iterates over the array printing its contents.With GNU sort:$ sort -nk2 file |  sort -u -k1,1Apple 3Banana 1Orange 2The first sort will print the lines in ascending order of weight (the 2nd field) and the second will only keep unique lines, but checks the 1st field only. The result is that the first occurrence of each string is printed which, because of the 1st sort, will be the smallest value for that fruit. And a (slightly) shorter 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 2Apple 3Banana 1The //= will assign a value unless the variable already has one. Then, the approach is the same as the awk one. We create the hash %k whose keys are the fruit and whose values their weight, and save the smallest value. The -a flag causes perl to act like awk and split its input on whitespace into the @F array.