Script Perl para comparar duas linhas consecutivas para o primeiro caractere e ignorar a segunda linha se ambos os primeiros caracteres forem os mesmos

2

Alguém pode ajudar como comparar duas linhas consecutivas de um arquivo de texto para o primeiro caractere e se os dois primeiros caracteres são os mesmos, ignore / exclua a segunda linha e imprima em um novo arquivo apenas a primeira linha.

#1001
#1002
mango
orange
grape
#1003

Eu quero excluir #1002 .

    
por keshav 22.07.2015 / 11:55

5 respostas

4

Usando o GNU uniq com a opção -w 1 :

  -w, --check-chars=N
          compare no more than N characters in lines

você pode omitir linhas duplicadas consecutivas, comparando apenas o primeiro caractere:

uniq -w1 infile >outfile

1. Isso não funcionará corretamente para caracteres de múltiplos bytes. Veja a nota de Stéphane abaixo

    
por 22.07.2015 / 12:41
1
perl -C -ne '$c = substr($_,0,1);
             print unless $c eq $l;
             $l = $c;' < file.in > file.out
    
por 22.07.2015 / 12:41
1
sed '$n;h;N;/^\(.\).*\n/g;/\n/P;//!G;D' <in >out

Há um script sed que faz isso.

Funciona assim:

  1. Se a linha atual for a última, imprima-a como padrão e termine o script.
  2. Se não, salve uma cópia da linha atual para manter o espaço.
  3. Em seguida, anexe a próxima linha de entrada ao espaço padrão.
  4. Se o primeiro caractere em espaço de padrão for idêntico ao primeiro caractere na linha que acabou de anexar, substitua o espaço de padrão pela cópia do espaço de espera salva.
  5. Se não, ainda teremos um \n ewline no espaço padrão, caso em que devemos Imprimir apenas até esse ponto.
  6. Se não, obtenha outra cópia de nossa linha retida anexada ao espaço padrão.
  7. Independentemente, exclua até a primeira nova linha no espaço padrão e comece novamente da parte superior do script com o que resta.

Essencialmente, ele trabalha com duas linhas por vez, imprimindo somente o primeiro quando o primeiro caractere na segunda linha não corresponde ao da primeira linha e substitui recursivamente as que fazem com a primeira ocorrência de uma série. E assim, ele pode manipular de maneira rápida e adequada a entrada de qualquer tamanho com o mínimo de buffering e apertar uma primeira série de correspondência de caracteres de qualquer tamanho a apenas sua primeira ocorrência. Ele funcionará com entrada em tempo real ou então com um arquivo, mas nunca precisará ler ou armazenar mais do que uma cópia da linha atual e da próxima.

    
por 22.07.2015 / 12:08
0
#!/usr/bin/perl
use warnings;
use strict;

my $first_line = <>;
my $second_line = <>;

if (substr($first_line, 0, 1) eq substr($second_line, 0, 1)) {
     print $first_line;
} else {
     # You didn't say what to do if the character are different.
}
    
por 22.07.2015 / 12:12
0
perl -0777 -pe '1 while s/^(.)(.*)\n.*/$1$2/gm' file.in >file.out

Isso absorve o arquivo inteiro e faz um loop até que nenhuma outra correspondência seja encontrada.

    
por 22.07.2015 / 17:18