Comparar e deletar linhas duplicadas em TXT

11/07/2008

0

Bom Dia Galera,

Fiz um programinha em delphi para substituir pipe | por ;
Ainda irei melhorar o programinha, mas irei postar aki p vocês caso alguém precise:

Function TForm1.GravaTxt(Texto : String; Destino : String) : String;
var
  arq: TextFile;
  linha: String;
begin

  AssignFile ( arq, Destino );

  If not(fileexists(Destino)) then
    Rewrite (arq )  // Apaga o Arq
  Else
    Append ( arq );     // Sobre escreve o Arq

  Writeln ( arq, Texto );     // Escreve

  CloseFile ( arq );


end;

Function TForm1.VerificaCMD(Texto : String) : String;
Begin
  If ( UpperCase(Texto) = ´$P´) Then  // O DOS não reconhece o caracter | (pipe)
    Result := ´|´                    //  portanto tive que criar um IF para sua identificação
  else
    Result := Texto;
End;


procedure TForm1.FormCreate(Sender: TObject);
var
  C : Integer;
  arq: TextFile;
  linha, nomeDoArquivo: String;
begin

  If (ParamCount <= 4) then
  Begin

    nomeDoArquivo :=  ParamStr(1);

    AssignFile ( arq, nomeDoArquivo  );

    Reset(arq);

    While not eof(arq) do
    Begin

      ReadLn ( arq, linha ); // Le.. // linha Atual pulando a linha

      linha := StringReplace(Linha, VerificaCMD(ParamStr(3))  , ParamStr(4) ,[rfReplaceAll]);

     if (linha == linha) them

      GravaTxt(Linha, ParamStr(2) );
     end;
    End;

    CloseFile ( arq );

    Close;
  End
  Else
    ShowMessage(´Somente é permitido no maximo 4 parametros!´);



  ExitProcess(0);


end;




end.



Uma das opções que preciso fazer neste programa, é ele ler todos os registros de um arquivo TXT e deletar o registro duplicado, exemplo:

[list:74d1c6a9e2]

João batista; 1; 2008
João batista; 1; 2008
José da Silva;2;2007
José da Silva;3;2008
Luciano Gomes;5;2001
Luciano Gomes;5;2001[/list:u:74d1c6a9e2]

O arquivo deverá ficar:

[list:74d1c6a9e2]
João batista; 1; 2008
José da Silva;2;2007
José da Silva;3;2008
Luciano Gomes;5;2001
[/list:u:74d1c6a9e2]


Shion86

Shion86

Responder

Posts

11/07/2008

Paulo

É possível que haja muitas formas de se fazer. No momento eu iria lendo linha-a-linha e guardando num variável. Se a próxima linha for identica ao conteúdo da variável eu deleto essa linha. Mas isso tem um problema; só vale para linhas repetidas imediatamente após a outra. Caso se repita em linhas alternadas, aí seria de outra forma. Mas como vi o seu exemplo, imediatamente após a outra, eu faria assim. Isto é só um entre muitas formas. Logo vc terá aqui nesse forum outras opções.


Responder

11/07/2008

Shion86

Valeu Paulo,
Estou pensando em fazer um for após ele ler o registro e excluir o dado, o grande problema é q eu estava utilizando .NET e me jogaram esse probleminha em delphi :shock:
mas obrigado pela ajuda, vou me esforçar aki p solucionar isso, já que preciso entregar hoje :cry:


Responder

14/07/2008

Fabianosales

Uma maneira bem simples de conseguir isto, Shion86, é utilizar uma instância de TStringList configurada para ignorar duplicidades.
Seu código ficaria asism:
var
  sl : TStringList;
  Origem, Destino, linha : string;
  f : TextFile;
begin
  Origem  := ´c:\temp\origem.txt´;
  Destino := ´c:\temp\destino.txt´;
  sl := TStringList.Create;

  //dupIgnore (Ignora as tentativas de adicionar itens duplicados à lista)
  sl.Duplicates := dupIgnore;
  try
    AssignFile(f, Origem);
    Reset(f);
    while not(Eof(f)) do
      begin
        Readln(f, linha);
        linha := StringReplace(StringReplace(linha, ´$P´, ´|´, [rfReplaceAll]), ´|´, ´;´, [rfReplaceAll]);
        sl.Add(linha);
      end;
  finally
    CloseFile(f);
  end;
  sl.SaveToFile(Destino);
  FreeAndNil(sl);
end;


Veja que a TStringList encapsula os algoritmos de busca e ordenação necessários para completar essa tarefa da maneira mais simples possível.


Responder

14/07/2008

Marco Salles

acho que num precisa percorrer linha por linha de TStringList

Acho que so isso resolve

Lista:=TstringList.create;
Lista.LoadFromFile(caminho);
lista.Text:=stringReplace(lista.Text,´|´, ´;´, [rfReplaceAll]);
lista.SaveToFile(caminho);
lista.free;



Responder

21/07/2008

Shion86

Valeu a ajuda galera, vou testar da forma que vocês postaram, mas fiz assim:

while not Eof(txtORIGINAL) do
     begin

          ReadLn(txtORIGINAL, sBufferOrig);

          sBufferOrig := TROCA_CARAC_BRANCO(sBufferOrig);

          if (sBufferOrig <> sBufferOrig_2) then
          begin
             {grava arquivo de saida}
              WriteLn(txtSAIDA, sBufferOrig);
          end;

          sBufferOrig_2 :=  sBufferOrig;

     end;


O código acima, irá comparar as linhas em sequencia, se forem iguais ele nao irá adicionar a ´repetida´, o único problema é que funciona apenas se os registros forem sequencias, agora se tiver assim:

joao
francisco
joao
mario
carlos

ele continuará gravando o joao novamente =/


Responder

21/07/2008

Paulo

Viu como vc teve várias respostas? Esse forum é assim, basta perguntar. Agora quanto a sua dúvida caso as linhas não sejam sequenciais, aí eu usaria o exemplo do fabianosales.


Responder

22/07/2008

Aroldo Zanela

Colega,

Para diversão, existem várias formas de se implementar isso. Entretanto, conforme já foi citado, o uso de instâncias da classe TStringList é a forma de menor esforço.

var
  Origem, Destino: TStringList;
  I, N: Integer;
begin
  Origem              := TStringList.Create;
  Destino             := TStringList.Create;
  // Note:Duplicates does nothing if the list is not sorted.
  Destino.Sorted      := True;
  Destino.Duplicates  := dupIgnore;

  Origem.LoadFromFile(´D:\JOB\Shion86\origem.txt´);

  N := Origem.Count-1;

  for I := 0 to N do
     Destino.Add(StringReplace(Origem.Strings[I], ´|´, ´;´, [rfReplaceAll]));

  Destino.SaveToFile(´D:\JOB\Shion86\destino.txt´);

  FreeAndNil(Origem);
  FreeAndNil(Destino);
end;



Responder

22/07/2008

Shion86

Valeuu a forçaaa galera!
Obrigado a todos mesmo..


Responder

22/07/2008

Marco Salles

eu ainda continuo achando que não é necessário percorrer toda a Tstring

for I := 0 to N do Destino.Add(StringReplace(Origem.Strings[I], ´|´, ´;´, [rfReplaceAll]))


por:
Destino.Text:=stringReplace(Origem.Text,´|´, ´;´, [rfReplaceAll]);


não funciona ??????


Responder

22/07/2008

Aroldo Zanela

Olá Marco,

Perfeito, você tem razão e podemos simplificar ainda mais:

var
  Arquivo: TStringList;
begin
  Arquivo              := TStringList.Create;
  // Note:   Duplicates does nothing if the list is not sorted.
  Arquivo.Sorted      := True;
  Arquivo.Duplicates  := dupIgnore;

  Arquivo.LoadFromFile(´D:\JOB\Shion86\Arquivo_texto.txt´);
  Arquivo.Text := StringReplace(Arquivo.Text, ´|´, ´;´, [rfReplaceAll]);
  Arquivo.SaveToFile(´D:\JOB\Shion86\Arquivo_texto.txt´);

  FreeAndNil(Arquivo);
end;



Responder

22/07/2008

Wdrocha

Oi Zanela e Marcos...


Estou acompanhando o tópico, pois achei interassante...e venho testando as soluções d vcs...


Tow aprendendo mt aq com vcs...



Vlw...


Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar