sort command compreendendo a sequência lógica

1

Alguém poderia me ajudar nisso: sort -k 2 nome_do_arquivo.txt significa que ele classifica pela segunda chave, mas o que significaria o seguinte comando: sort -k 3.3.3.5 para este dado: Por exemplo: eu tenho isso - >

Man in     Winter     England        1980.12.02                   
Richrd     Fritz      Scottland      1960.12.18
Max        Winter     GB             1955.12.09
Luther     Arnold     England        1990.05.12
Sebastian  Kalle      USA            1980.12.14

Como posso obter a solução para essa lista com este comando: sort -k 3.3.3.5 data.txt?

E como você pode classificá-lo quando você tem dois números decimais em geral?

Estou muito feliz por qualquer dica ou ajuda sobre este caso.

Atenciosamente abdi

    
por Abdi 14.02.2017 / 21:05

1 resposta

1

Vamos supor que não haja guias na entrada. A interpretação do comando é bastante complicada:

sort -k3.3,3.5

significa "classificar por uma substring do terceiro campo do terceiro ao quinto caractere", mas a contagem começa no primeiro espaço em branco antes do campo, como mencionado em man sort :

KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a field number and C a character position in the field; both are origin 1, and the stop position defaults to the line's end. If neither -t nor -b is in effect, characters in a field are counted from the beginning of the preceding whitespace.

Execute a classificação em LC_ALL = C para evitar que o local influencie na ordem de classificação.

Observe como a ordem muda se você adicionar mais um caractere, por exemplo

LC_ALL=C sort -k3.3,3.6

Aqui está um pequeno script em Perl que mostra qual parte da entrada é usada para classificação:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $field_index = 3;
my $start       = 3;
my $stop        = 5; # Change to 6 to explain the different order.

while (my $line = <>) {
    chomp $line;
    my @fields = $line =~ /(\s*\S*)/g;

    my $length_before = 0;
    $length_before += length $fields[$_] for 0 .. $field_index - 2;

    my $from = $start - 1 + $length_before;
    my $to   = $stop + $length_before;
    $_ > length $line and $_ = length $line for $from, $to;

    substr $line, $to, 0, '>>';
    substr $line, $from, 0, '<<';

    say $line;
}

Saída para 3.3.3.5:

Luther     Arnold  <<   >>England        1990.05.12
Man in  <<   >>Winter     England        1980.12.02                   
Max        Winter  <<   >>GB             1955.12.09
Richrd     Fritz  <<   >> Scottland      1960.12.18
Sebastian  Kalle  <<   >> USA            1980.12.14

Saída para 3.3.3.6:

Richrd     Fritz  <<    >>Scottland      1960.12.18
Sebastian  Kalle  <<    >>USA            1980.12.14
Luther     Arnold  <<   E>>ngland        1990.05.12
Max        Winter  <<   G>>B             1955.12.09
Man in  <<   W>>inter     England        1980.12.02
    
por 14.02.2017 / 21:52