Processamento de texto apenas para condições atendidas da linha X a Y

5

Como podemos excluir linhas duplicadas vistas apenas nas linhas X a Y e alterar o arquivo no local?

Por exemplo, se eu quiser apenas excluir linhas duplicadas da linha 10 a 20.

    
por Parsa Samet 07.08.2016 / 18:38

4 respostas

4

Com o GNU awk (4.1.0 ou superior para o recurso inplace ):

gawk -i inplace '
  NR >= 10 && NR <= 20 {
    if ($0 in seen) next
    seen[$0]
  }
  {print}' ./file

Ou com perl :

perl -ni -e 'print if $. < 10 or $. > 20 or !$seen{$_}++' ./file

Para processar vários arquivos:

gawk -i inplace '
  BEGINFILE{delete seen}
  FNR >= 10 && FNR <= 20 {
    if ($0 in seen) next
    seen[$0]
  }
  {print}' ./*.txt

Ou com perl :

perl -ni -e '
  print if $. < 10 or $. > 20 or !$seen{$_}++;
  if (eof) {close ARGV; undef %seen}' ./*.txt
    
por 08.08.2016 / 13:18
3

awk é seu amigo

awk '{
      if(NR>=10 && NR<=20)
      {
        if($0 in record){
         next
        }else{
         print;
         record[$0];
        }
     }
     else{
        print
     }
     }' file > temp && mv temp file
    
por 07.08.2016 / 18:47
2

Se OP precisar remover linhas que duplicam apenas dentro de 10 a 20 linhas:

sed -i '
    :a; 10,19!b; N; s/\(^\|\n\)\([^\n]*\)\n\(\(.\+\n\|\)$\)//; ba
       ' file1 file2 ...
    
por 08.08.2016 / 10:45
1

Os mesmos truques aplicados nas respostas baseadas em Perl também podem ser usados para encurtar o código Awk, e ele fica menor e mais limpo:

awk 'NR < 10 || NR > 20 || !seen[$0]++'
   ^ ^          ^           ^
   | |          |           |
   | \__________\___________\______ no sigil noise
   |
   \_ no options here to remember
      (unless we want that Gawk inplace semantics)

Os contadores não estourarão porque o intervalo é restrito a dez linhas - e o GNU Awk tem números inteiros bignum de qualquer maneira.

    
por 02.09.2016 / 03:59