Só deixa linha mais longa quando a primeira coluna é duplicada

2

ENTRADA:

user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u
'ST30074650'        '2015-10-17 10:00'
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
user@server:~/bar/foobar$ 

SAÍDA NECESSÁRIA:

user@server:~/bar/foobar$ SAT=$(date -dsaturday +%Y-%m-%d); SUN=$(date -dsunday +%Y-%m-%d)
user@server:~/bar/foobar$ awk 'BEGIN {FS="'^'"} {print $1"\t"$3"\t"$6}' STs.csv STt.csv | egrep -w "${SAT}|${SUN}" | sort -u | SOMEMAGIC
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
user@server:~/bar/foobar$ 

Pergunta : Então, se houver uma primeira coluna duplicada, ex .: "ST30074650" - a linha mais longa deve permanecer apenas. Como alguém poderia fazer isso no "SOMEMAGIC".

    
por LoukiosValentine79 14.10.2015 / 09:20

4 respostas

2
user@machine:~/tmp$ cat f1
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30124587'        '2015-10-18 09:00'
'ST30123591'        '2015-10-18 09:00'
'ST30074650'        '2015-10-17 10:00'

user@machine:~/tmp$ sort -r f1 |uniq -w 12 |sort
'ST30074650'    '[email protected]'  '2015-10-17 10:00'
'ST30085367'    '[email protected]'  '2015-10-18 13:00'
'ST30086369'        '2015-10-17 13:00'
'ST30115016'    '[email protected]'  '2015-10-18 13:00'
'ST30123591'        '2015-10-18 09:00'
'ST30124587'        '2015-10-18 09:00'
  • Primeiro, classifique em ordem inversa na linha inteira para obter linhas mais longas primeiro
  • uniq apenas verifica primeiro 12 caracteres reterão a primeira linha (mais longa) comparando apenas 12 caracteres
  • ordenação final opcional para obter ordem natural
por 14.10.2015 / 09:51
3

Eu não vejo o que SOMEMAGIC tem a ver com isso

experimente este arquivo awk

{ if ( $1 in a ) {
     if ( length(a[$1]) < length($0)) a[$1]=$0 ;
            } # $1 in a
  else  a[$1]=$0 ; }

END { for ( b in a ) {print a[b] ;}  }

use-o com (sem necessidade de ordenação prévia)

... egrep -w "${SAT}|${SUN}" | awk -f u.awk | sort
    
por 14.10.2015 / 09:45
3

Usando um perl one-liner:

perl -a -e '$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ; END { foreach (sort keys %line) { print $line{$_} } };'  STs.csv STt.csv

Ou, em um formulário de script perl autônomo mais fácil de ler:

#! /usr/bin/perl -a

$line{$F[0]} = $_ if (length($_) > length($line{$F[0]})) ;

END {
  foreach (sort keys %line) { print $line{$_} }
};

Este é essencialmente o mesmo algoritmo da resposta de Archemar, mas em perl em vez de awk . Em termos simples: usando o primeiro campo da entrada como a chave para um array com hash, se a linha atual de entrada for maior que o que nós armazenamos para o array (o padrão é a string vazia em perl) então armazene a linha atual. Depois de lermos todas as entradas (ou seja, acabadas), imprimamos cada elemento do hash.

    
por 14.10.2015 / 10:01
0

refatorando seu código (não testado devido à falta de dados de entrada brutos)

awk -F '^' -v OFS='\t' \
           -v sat=$(date -d saturday +%F) \
           -v sun=$(date -d sunday +%F) \
'
    $6 !~ "^"sat && $6 !~ "^"sun {next}
    { line = $1 OFS $3 OFS $6 }
    length(line) > lines[$1] {lines[$1] = line}
    END { for (key in lines) print lines[key] }
' STs.csv STt.csv | sort

Com o GNU awk, você pode omitir o sort à direita usando

    END { 
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (key in lines) print lines[key] 
    }
    
por 14.10.2015 / 20:51

Tags