Remove linha duplicada se existir a coluna 2

1

Estou trabalhando com dados de amostra, com mais de 10 mil linhas, semelhante ao seguinte:

hxxp://google.com 
hxxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://yahoo.com 
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://a.com
hxxp://b.com "good"
hxxp://c.com
hxxp://c.com "good"
hxxp://c.com

Estou tentando encontrar uma maneira de alcançar esses resultados:

hxxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://b.com "good"
hxxp://c.com "good"

Nos dados da amostra, pode haver uma linha duplicada. Se houver uma linha duplicada, exclua a linha que está faltando uma segunda coluna. O delimitador é o espaço.

awk -F' ' '!seen[$1]++' dupe.txt > clean.txt

Isso não parece ser o forro certo para mim.

    
por mernix 27.07.2018 / 17:37

4 respostas

2
$ LC_ALL=C sort -r <file | LC_ALL=C sort -k1,1 -us
hxxp://a.com "good"
hxxp://about.com
hxxp://b.com "good"
hxxp://c.com "good"
hxxp://google.com "Seen"
hxxp://reddit.com
hxxp://x.com
hxxp://y.com
hxxp://yahoo.com "Check again"
hxxp://z.com

O primeiro sort ordena o arquivo na ordem inversa, usando a linha inteira como chave de classificação. Isso resultará no resultado intermediário

hxxp://z.com
hxxp://yahoo.com "Check again"
hxxp://yahoo.com
hxxp://y.com
hxxp://x.com
hxxp://reddit.com
hxxp://google.com "Seen"
hxxp://google.com
hxxp://c.com "good"
hxxp://c.com
hxxp://c.com
hxxp://b.com "good"
hxxp://about.com
hxxp://a.com "good"
hxxp://a.com

dados dados do exemplo. Observe como as linhas que contêm anotações extras sempre vêm antes das linhas correspondentes, sem anotações extras.

O segundo sort produz apenas linhas cuja chave de classificação é exclusiva. Usamos apenas o primeiro campo (o URL) como chave de classificação. Também pedimos que sort use um algoritmo de classificação "estável" com -s . Isso significa que a ordem das linhas com chaves idênticas não mudará do que está na entrada.

A combinação -u e -s fornece apenas as linhas com anotações extras para os URLs repetidos.

O LC_ALL=C bit é para garantir que sort obtenha um código de idioma sã para que as linhas sejam classificadas corretamente para que isso funcione.

    
por 27.07.2018 / 17:49
1

se o seu exemplo contiver todos os estados e assumir o seu arquivo chamado Sample.data:

grep " " Sample.data > Result
cut -d' ' -f1 Result > FirstCol
grep Sample.data -v -f FirstCol >> Result
    
por 27.07.2018 / 18:53
0

Você pode fazer isso:

awk '
    !($1 in a) || NF > 1 {a[$1] = $0} 
    END {for (url in a) print a[url]}
' dupe.txt

A ordem das linhas não será preservada.

Isso manterá o pedido, mas exigirá 2 passagens pelo arquivo:

awk '
    NR == FNR {
        if (!($1 in a) || NF > 1) {a[$1] = $0} 
        next
    }
    $0 == a[$1]
' dupe.txt dupe.txt
    
por 27.07.2018 / 17:44
0
perl -lane '
    push @h, $F[0] if ! exists $h{$F[0]};
    $h{$F[0]} = $_ if ! exists $h{$F[0]} || @F > 1;
    }{ print $h{$_} for @h;
' dupe.txt > clean.txt

Explicação:

  • @h armazena a ordem em que as chaves, ou seja, os primeiros campos são encontrados.
  • %h é o hash que é digitado no primeiro campo, $F[0] e os valores correspondentes são as linhas no total.
  • Os valores do hash %h são atualizados toda vez que uma nova chave é vista OU quando vemos uma chave antiga, mas a linha tem mais de um campo e, nesse caso, está madura para updation.
  • No eof , simplesmente passamos as chaves armazenadas na matriz @h e retiramos os valores correspondentes e levamos para a stdout.

Saída:

xxp://google.com "Seen"
hxxp://yahoo.com "Check again"
hxxp://about.com
hxxp://x.com
hxxp://y.com
hxxp://z.com
hxxp://reddit.com
hxxp://a.com "good"
hxxp://b.com "good"
hxxp://c.com "good"
    
por 28.07.2018 / 20:30

Tags