Encontre os menores números na segunda coluna correspondentes aos valores de índice na primeira coluna

1

Eu tenho algumas tabelas muito grandes e preciso extrair linhas específicas. Eu estou ilustrando a tarefa usando um exemplo simples. Diga, eu pesava um número de maçãs, bananas e laranjas. Eu preciso extrair o peso da menor maçã, banana e laranja

Tabela original:

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

Saída desejada:

Apple 3
Banana 1
Orange 2
    
por Nasir 03.10.2015 / 16:13

4 respostas

2

com 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 configura um array chamado a , cujas chaves são o primeiro campo e cujo valor é o segundo. O script acima salvará o segundo campo como o valor da primeira na matriz se i) for menor que o valor armazenado ou ii) não houver valor armazenado. O bloco END itera no array, imprimindo seu conteúdo.

Com o GNU sort :

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

A primeira classificação imprimirá as linhas em ordem crescente de peso (o segundo campo) e a segunda manterá linhas únicas, mas verifica apenas o primeiro campo. O resultado é que a primeira ocorrência de cada string é impressa e, por causa do primeiro tipo, será o menor valor para essa fruta.

E um Perl (ligeiramente) mais curto:

$ 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

O //= atribuirá um valor a menos que a variável já tenha um. Então, a abordagem é a mesma que a awk one. Criamos o hash %k cujas chaves são o fruto e cujos valores são o seu peso, além de salvar o menor valor. O sinal -a faz com que perl aja como awk e divida sua entrada no espaço em branco na matriz @F .

    
por 03.10.2015 / 17:27
3

Com gnu datamash :

datamash -s -g 1 min 2 <infile
Apple 3
Banana 1
Orange 2

Este campo s orts e g grupos por 1 st imprimindo o campo min em 2 nd para cada ID no primeiro campo. Ele assume que os campos estão separados por uma única guia. Use -W, --whitespace se eles estiverem separados por vários espaços em branco ou -t, --field-separator= para definir outro separador de campo, por exemplo, espaço único:

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

Como datamash requer entrada classificada, a saída também será classificada pelo 1º campo.

    
por 03.10.2015 / 16:51
2

Você pode fazer isso usando 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

Aqui estamos usando um mapa de hash (% h) para armazenar elementos. Se a fruta ainda não está presente no hash, adicionamos seu primeiro valor, se já existir, atualizamos o valor apenas se ele for menor que o valor já armazenado. O bloco END é executado somente depois que a última linha do arquivo é processada, ele imprime o mapa de hash.

    
por 03.10.2015 / 16:54
1
sort -k2,2n file | sort -u -k1,1

Saída:

Apple 3
Banana 1
Orange 2
    
por 03.10.2015 / 17:28