Eu quero encontrar duplicatas em um arquivo e adicionar um caractere ao final da linha no primeiro jogo

2

Estou tentando encontrar duplicatas em um arquivo e, uma vez encontrada uma correspondência, marque a primeira correspondência com um caractere ou palavra no final da linha.

por exemplo, meu arquivo (test.html) contém as seguintes entradas

host= alpha-sfserver1
host= alphacrest3
host= alphacrest4
host= alphactn1 
host= alphactn2
host= alphactn3 
host= alphactn4
down alphacrest4

Eu posso encontrar a duplicata usando o seguinte: - (Eu uso $ 2 como a duplicata sempre estará na coluna 2)

awk '{if (++dup[$2] == 1) print $0;}' test.html

Ele removeu a última entrada (down alphacrest4), mas o que eu quero é marcar também a entrada duplicada com uma palavra ou caractere como: -

host= alphacrest4 acked

Qualquer ajuda é muito bem-vinda.

    
por Sean 03.06.2013 / 16:58

3 respostas

1

Você precisa processar o arquivo duas vezes. Na primeira execução, você escreve os dupes em um arquivo:

awk '{if (++dup[$2] == 1) print $2;}' test.html > dupes.txt

A segunda execução compara todas as linhas com o conteúdo do arquivo:

awk 'BEGIN { while (getline var <"dupes.txt") { dup2[var]=1; }};
  { num=++dup[$2]
    if (num == 1) { if (1 == dup2[$2]) print $0 " acked"; else print $0;} }' \
test.html
    
por 03.06.2013 / 17:46
1

Isso seria muito mais fácil se tivéssemos o arquivo inteiro. Você está interessado apenas nas linhas que começam com host= ou qualquer dos 2os campos? Para uma solução geral, tente isto:

perl -e '@file=<>; 
         foreach(map{/.+?\s+(.+)/;}@file){$dup{$_}++};  
         foreach(@file){
              chomp; 
              /.+?\s+(.+)/; 
              if($dup{$1}>1 && not defined($p{$1})){
                 print "$_ acked\n";
                 $p{$1}++;}
              else{print "$_\n"}
          }' test.html 

O script acima lerá primeiro o arquivo inteiro, verificará se há duplicatas e imprimirá cada linha duplicada seguida de "acked".

A coisa toda é muito mais simples se pudermos supor que você está interessado apenas em linhas que começam com down X :

grep down test.html | awk '{printf $2}' | 
 perl -e 'while(<>){$dup{$_}++}open(A,"test.html"); 
   while(<A>){
    if(/host=\s+(.+)/ && defined($dup{$1})){
      chomp; print "$_ acked\n"}
    else{print}}' 
    
por 03.06.2013 / 17:47
1

Isso pode ajudar:

One-Liner:

awk 'NR==FNR{b[$2]++; next} $2 in b { if (b[$2]>1) { print $0" acked" ; delete b[$2]} else print $0}' inputFile inputFile

Explicação:

awk '
NR==FNR { 

        ## Loop through the file and check which line is repeated based on column 2

        b[$2]++

        ## Skip the rest of the actions until complete file is scanned

        next
} 

## Once the scan is complete, look for second column in the array

$2 in b { 

        ## If the count of the column is greater than 1 it means there is duplicate.

        if (b[$2]>1) { 

            ## So print that line with "acked" marker

            print $0" acked"

            ## and delete the array so that it is not printed again

            delete b[$2]
        } 

        ## If count is 1 it means there was no duplicate so print the line

        else 
            print $0
}' inputFile inputFile
    
por 03.06.2013 / 20:15