Comparar e deletar linhas duplicadas em TXT
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:
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]
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
Curtidas 0
Respostas
Paulo
11/07/2008
É 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.
GOSTEI 0
Shion86
11/07/2008
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:
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:
GOSTEI 0
Fabianosales
11/07/2008
Uma maneira bem simples de conseguir isto, Shion86, é utilizar uma instância de TStringList configurada para ignorar duplicidades.
Seu código ficaria asism:
Veja que a TStringList encapsula os algoritmos de busca e ordenação necessários para completar essa tarefa da maneira mais simples possível.
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.
GOSTEI 0
Marco Salles
11/07/2008
acho que num precisa percorrer linha por linha de TStringList
Acho que so isso resolve
Acho que so isso resolve
Lista:=TstringList.create; Lista.LoadFromFile(caminho); lista.Text:=stringReplace(lista.Text,´|´, ´;´, [rfReplaceAll]); lista.SaveToFile(caminho); lista.free;
GOSTEI 0
Shion86
11/07/2008
Valeu a ajuda galera, vou testar da forma que vocês postaram, mas fiz assim:
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 =/
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 =/
GOSTEI 0
Paulo
11/07/2008
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.
GOSTEI 0
Aroldo Zanela
11/07/2008
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.
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;
GOSTEI 0
Shion86
11/07/2008
Valeuu a forçaaa galera!
Obrigado a todos mesmo..
Obrigado a todos mesmo..
GOSTEI 0
Marco Salles
11/07/2008
eu ainda continuo achando que não é necessário percorrer toda a Tstring
por:
não funciona ??????
for I := 0 to N do
Destino.Add(StringReplace(Origem.Strings[I], ´|´, ´;´, [rfReplaceAll]))
por:
Destino.Text:=stringReplace(Origem.Text,´|´, ´;´, [rfReplaceAll]);
não funciona ??????
GOSTEI 0
Aroldo Zanela
11/07/2008
Olá Marco,
Perfeito, você tem razão e podemos simplificar ainda mais:
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;
GOSTEI 0
Wdrocha
11/07/2008
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...
Estou acompanhando o tópico, pois achei interassante...e venho testando as soluções d vcs...
Tow aprendendo mt aq com vcs...
Vlw...
GOSTEI 0