
eu tenho uma lista enorme como
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
quero pesquisar mais número duplicado após 2; e antes do 3º;
para a primeira linha o número é 5450-7938-7992-5530
e outra linha 4532-4142-5613-9690
e etc
Responder1
Considere o seguinte script awk duplicates.awk
:
#!/usr/bin/awk -f
BEGIN {
RS = "(\r\n|\n\r|\r|\n)"
FS = "[\t\v\f ]*;[\t\v\f ]*"
split("", count)
}
{
count[$3]++
}
END {
for (item in count) {
if (count[item] > 1)
printf "%s\n", item
}
}
Lembre-se de torná-lo executável, usando, por exemplo chmod a+rx duplicates.awk
, . Você pode canalizar a entrada para o comando ou fornecer um ou mais arquivos de entrada como parâmetros de linha de comando (vários arquivos são tratados como se estivessem concatenados em um único arquivo).
A regra BEGIN configura novas linhas universais (ou seja, aceita todas as convenções de nova linha do MS-DOS aos Macs antigos e ao Unix) e ponto-e-vírgula ;
como separador de campos. Para ilustração, fiz com que o separador de campos também consumisse qualquer espaço em branco ao seu redor, de modo que x;foo bar ; y
seja analisado em três campos: x
, foo bar
, e y
.
A regra de registro (a parte central do snippet) é aplicada a cada registro (linha) na entrada. Como o awk suporta arrays associativos, simplesmente usamos o terceiro campo, uma string, como chave para count
o array, e incrementamos essa entrada em um. (Incrementar uma entrada de array inexistente no awk produz 1, então o primeiro incremento produz 1 e o código funciona como esperado.)
A regra END verifica o count
array, imprimindo as entradas que ocorreram pelo menos duas vezes. Observe que esta saída está em ordem aleatória. (Existem maneiras de classificar a saída de acordo com o número de ocorrências, ou até mesmo de manter a ordem original (das primeiras ocorrências) no arquivo, mas o OP não mencionou nenhum requisito wrt. ordering, então não me preocupei; indefinido ordem é a mais simples de implementar.)
Se você quiser imprimir, por exemplo, o número de ocorrências seguido pela string (o valor da terceira coluna), use a seguinte regra END:
END {
for (item in count)
printf "%15d %s\n", count[item], item
}
A saída é formatada de forma que os primeiros quinze caracteres da saída sejam reservados para o número e o valor comece no 17º caractere.
Responder2
Criando alguns valores duplicados no arquivo stack.txt e depois imprimindo a saída -
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
62562;4532-5581-3790-0140;5292-4905-4356-2840;28898987;03 Oct 2016 - 17:01:15
68080;5188-1564-9611-7580;4556-9998-5999-3300;2262361;03 Oct 2016 - 17:01:15
67603;4716-5469-1335-0870;5450-7938-7992-5530;14523593;03 Oct 2016 - 17:01:15
63123;5592-6762-4853-6320;4532-4142-5613-9690;1441407;03 Oct 2016 - 17:01:15
Use o comando abaixo -
awk 'BEGIN{FS=";"}{a[$3]++} END {for(k in a) print a[k],k}' stack.txt
Saída -
3 4532-4142-5613-9690
2 5292-4905-4356-2840
3 5450-7938-7992-5530
2 4556-9998-5999-3300