Arquivo TXT

Fórum sobre a linguagem CA-Clipper.

Moderador: Moderadores

Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Arquivo TXT

Mensagem por Valentim »

Como posso remover determinadas linhas de um arquivo de LOG e escrever um novo arquivo .txt?

Por exemplo:

Código: Selecionar todos

Linha 01: RCS file: /cvs/1.fmb,v
Linha 02: head: 1.5
Linha 03: locks: strict
Linha 04: total revisions: 6;	selected revisions: 1
Linha 05: description:
Quero escrever o novo arquivo .txt com as seguintes linhas 02 e 04 e apagar as outras linhas sem deixar espaços em branco.

se alguem puder ajudar...
Muito Obrigado
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

Seja bem-vindo ao fórum. :)

Se sua dúvida é com relação ao melhor tipo de procedimento:
Acho que a melhor alternativa, que eu adotaria, aliás, é renomear o arquivo original, ler este arquivo linha a linha, e gravar no arquivo destino apenas as que desejar salvar.

Se sua dúvida é com relação à técnica dentro do conceito da linguagem:
Eu sempre prefido utilizar as funções de manipulação de arquivo em baixo nível: FCreate(), FOpen(), etc. Me sinto mais à vontade com elas. Até porque, com elas a performance é melhor. Mas você também poderia utilizar as funções MemoRead() e MemoWrite() (nunca usei). Mas ainda assim você terá que separar as linhas.

Se não consegui esclarecer muita coisa, especifique melhor qual é sua dúvida.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

Obrigado Maligno,

Sou meio novato na linguagem Clipper, tentei fazer esse programinha mais pra facilitar a minha vida, pois estou precisando editar um arquivo com mais de 5 mil linhas e capturar somente essas linhas que informei.

No Programa que estou tentando fazer a duvida e como buscar as linhas que que quero OU como apagar as linhas que não quero....
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

Esse assunto já foi discutido algumas vezes. Certa vez postei um código simples, para efeito de exemplo. Acho que ele pode ajudá-lo a ter um ponto de partida.

Código: Selecionar todos

#define _kSIZE 16*1024
#define _kEOL  Chr(13)+Chr(10) 


//------------------------------------------------------------ 
function Leitura(cFileN) 
local nByts                         // bytes lidos na iteração 
local nLins  := 0                   // quantidade de linhas 
local cBuff  := Space(_kSIZE)       // buffer de armazenamento 
local cRest  := ""                  // resto da leitura 
local cFileH := FOpen(cFileN)) = -1 // alça do arquivo aberto 
* 
if nFileH = -1 
   // Erro na abertura do arquivo! Trate o erro à sua maneira 
   return .F. 
end 
* 
while (nByts := FRead(cFileH,@cBuff,_kSIZE)) > 0 .or. !Empty(cRest) 
   cBuff := RTrim(cBuff) 
   cBuff := cRest+cBuff 
   cBuff += if(nByts=0 .and. Right(cBuff,2) != _kEOL, _kEOL, "") 
   // 
   // Individualização da linha através do par CR/LF (_kEOL) 
   while (i := At(_kEOL,cBuff)) > 0 
      // A linha já individualizada, sem _kEOL 
      cLine := Left(cBuff,i-1) 
      // Ajuste do buffer, descartando o _kEOL 
      cBuff := SubStr(cBuff,i+2) 
      // Contador de linhas, caso precise 
      nLins ++ 
      // 
      // 
      // Neste ponto você poderá fazer sua pesquisa 
      // dentro da linha, usando as funções básicas 
      // do Clipper. 
      // 
      // 
   end 
   // Pode sobrar algo após o último _kEOL 
   cRest := cBuff 
   // Reset do buffer para nova leitura 
   cBuff := Space(_kSIZE) 
end
return .T.
Preparei para ele "puxar" 16KB de vez. Note que o Clipper tem um limite de 64KB. Mas se precisar, mude a constante _kSIZE para o tamanho que achar mais apropriado, até o limite do Clipper.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

Não entendi completamente o código passado, só estou tentando encontrar um conjunto de caracteres em uma string para cada linha do arquivo, para apagar a linha OU gravar a mesma em outro arquivo.

Mas mesmo assim vou tentar utilizar algumas coisas para ver se consigo algo.
Obrigado
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

O código não é tão difícil de entender quanto parece. Ele abre o arquivo origem e carrega pedaços dele para a memória. Esse buffer é trabalhado dentro da malha WHILE, para que sejam separadas as linhas, que a partir daí poderão ser analisadas separadamente.

Há diversas formas de fazer o que você quer. Essa é apenas uma delas. :)
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

Cheguei até a utilizar o SDF pra passar o arquivo TXT pra DBF mais ta complicado escrever o novo arquivo com as linhas corretas

meu programinha aqui ta uma loucura, nem eu to entendendo mais o que tou fazendo
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Mensagem por Pablo César »

Valentim escreveu:Cheguei até a utilizar o SDF pra passar o arquivo TXT pra DBF
O que não estaria errado. O exemplo dado pelo Maligno é feito diretamente no arquivo TXT em baixo nível (é correto também).

Se você ainda tiver o procedimento que importa o TXT para o DBF você poderá tratar (isto é eliminar as linhas) no DBF mesmo. Você tem alguma referência que queira mencionar para tê-la como condição ?. Ou seria conviente apresentar na tela e apagar manualmente ou até selecionar as linhas que deseja apagar. Se for isto que precisa, é só exibí-las num TBROWSE. Uma vez que você selecionou o que tem que ser deletado é só deletar e gerar o arquivo (com o mesmo nome), mas tem que ter certeza que o SET DELETED esteja ON

Obs.: Se este arquivo de LG está numa rede, você precisará fazer um semáforo que nesse momento de apagar as linhas do LOG, ninguém possa a vir a gravar, porque senão vai se perder nessa "manutenção".
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

Estou quase conseguindo utilizando o SDF e a função AT do Clipper, porém ainda estou aperfeiçoando... caso eu não consiga completar volto aqui novamente para tirar mais algumas duvidas :)
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

1. Pronto, consegui fazer uma parte utilizando o seguinte código...

Código: Selecionar todos

cRCS := cRev := cDtAu := cDesc := ""
cArqTmp := "CVS"
aTemp   := {}

Aadd (aTemp, {"TEXTO","C",300,0})
DBCreate (cArqTmp, aTemp)
DBUseArea ( .t.,,cArqTmp,, .f., .f.)
Append From log_cvs.txt SDF

SET PRINTER ON
SET DEVICE TO PRINTER
SET PRINTER TO LogCVS.txt
SET CONSOLE OFF
SET CURSOR OFF

DBGoTop()
Do While !Eof()
  cLoc1    := "RCS file: "
  nPosIni1 := AT(cLoc1,TEXTO)
  nPosFim1 := AT(",v",SubStr(TEXTO,nPosIni1,Len(TEXTO)))
  if nPosFim1 > 0
    cRCS := SubStr(TEXTO,nPosIni1,nPosFim1-nPosIni1)
    @ PROW() + 00,00 SAY cRCS
  endif
  
  cLoc2  := "revision "
  nPosIni2 := AT(cLoc2,TEXTO)
  nPosFim2 := AT("revision ",SubStr(TEXTO,nPosIni2,Len(TEXTO)))
  if nPosFim2 > 0
    cRev := SubStr(TEXTO,nPosIni2,(nPosFim2+20)-nPosIni2)
    @ PROW() + 01,00 SAY cRev
  endif
  
  cLoc3    := "date: "
  nPosIni3 := AT(cLoc3,TEXTO)
  nPosFim3 := AT(";  state: ",SubStr(TEXTO,nPosIni3,Len(TEXTO)))
  if nPosFim3 > 0
    cDtAu := SubStr(TEXTO,nPosIni3,(nPosFim3+1)-nPosIni3)
    @ PROW() + 01,00 SAY cDtAu
    @ PROW() + 01,00 SAY Replicate('=',77)
    @ PROW() + 01,00 SAY ""
  endif

  DBSkip()
EndDo
2. Porém está faltando a parte da "descrição", vou mostrar um exemplo completo do arquivo de leitura...

Código: Selecionar todos

RCS file: /u01/cvs/rps-v48/acma/M_SOLICITACAO_SERV.fmb,v
Working file: M_SOLICITACAO_SERV.fmb
head: 1.20
branch:
locks: strict
access list:
keyword substitution: b
total revisions: 28;	selected revisions: 1
description:
----------------------------
revision 1.17
date: 2007/09/14 18:36:48;  author: author001;  state: Exp;  lines: +354 -296
/*
PDA 201138 - 14/09/2007 - D.F.N.
DESCRIÇÃO: Na Trigger WHEN-VALIDATE-ITEM do campo CD_BEM e DSP_DS_PLAQUETA, alterada a consulta, pois não trazia
o código do Setor
*/
=============================================================================

RCS file: /u01/cvs/rps-v48/acma/M_TIPO_OS.fmb,v
Working file: M_TIPO_OS.fmb
head: 1.8
branch:
locks: strict
access list:
keyword substitution: b
total revisions: 9;	selected revisions: 1
description:
----------------------------
revision 1.6
date: 2007/04/13 18:26:24;  author: author002;  state: Exp;  lines: +142 -206
recompilacao
=============================================================================

RCS file: /u01/cvs/rps-v48/acma/R_ABERTURAOS.rdf,v
Working file: R_ABERTURAOS.rdf
head: 1.6
branch:
locks: strict
access list:
keyword substitution: b
total revisions: 9;	selected revisions: 1
description:
----------------------------
revision 1.6
date: 2007/04/29 19:05:11;  author: author003;  state: Exp;  lines: +3965 -1612
PDA 178252
Substituida a trigger after repport pela formula CF_ATUALIZAOSIMPRESSA
=============================================================================
3. A "Descrição" seria todos o texto abaixo da linha onde é informado "Date", "Author", "State" e "Lines" até a linha ======

4. O Resultado está da seguinte maneira (Sem a "Descrição" que é fundamental)

Código: Selecionar todos

RCS file: /u01/cvs/rps-v48/acma/M_SOLICITACAO_SERV.fmb,v
revision 1.17
date: 2007/09/14 18:36:48;  author: author001;
=============================================================================

RCS file: /u01/cvs/rps-v48/acma/M_TIPO_OS.fmb,v
revision 1.6
date: 2007/04/13 18:26:24;  author: author002;
=============================================================================

RCS file: /u01/cvs/rps-v48/acma/R_ABERTURAOS.rdf,v
revision 1.6
date: 2007/04/29 19:05:11;  author: author003;
=============================================================================
Alguém teria alguma idéia de como fazer para capturar a Descrição...
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Mensagem por Maligno »

Repare que o que você quer é a linha que inicia com RCS, a linha que inicia com revisision e a linha que inicia com date. Essas são suas pistas. Uma vez que todas as linhas estão devidamente separadas, basta analisar cada linha em busca dessas strings chave.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Valentim
Usuário Nível 1
Usuário Nível 1
Mensagens: 7
Registrado em: 19 Fev 2008 13:55
Localização: Recife - PE

Mensagem por Valentim »

Exatamente, o meu problema está sendo capturar vários registros do dbf...
por exemplo, capturar o registro 11 até 16

Código: Selecionar todos

Registro XX: AAAAAAAAAAAAAAAAAAAAAAA
Registro 11: /*
Registro 12: PDA 201138 - 14/09/2007 - D.F.N.
Registro 13: DESCRIÇÃO: Na Trigger WHEN-VALIDATE-ITEM do campo CD_BEM e Registro 14: DSP_DS_PLAQUETA, alterada a consulta, pois não trazia
Registro 15: o código do Setor
Registro 16: */ 
Registro XX: AAAAAAAAAAAAAAAAAAAAAAAA
qual a "pista" para ele capturar esses registros se eles podem ser completamentes diferentes? :(
Manuel Luis Modernel
Usuário Nível 2
Usuário Nível 2
Mensagens: 66
Registrado em: 02 Mar 2008 20:40
Localização: São José do Rio Preto - SP

escolher alguns poucos registros em sequencia ascendente

Mensagem por Manuel Luis Modernel »

OI Valentim,

Uns 13 anos atras fiz alguma coisa em Clipper Summer 87, não sei se entendi teu problema mais eu fazia assim:

Indexava o DBF por item (se necessário colocava mais um campo numerico indicando no teu casso os numeros dos campos 11 a 16, dai com um Seek ia até o nº 11 e com varios Skeep num While - Loop chegava até registro nº 16 depois saia do dbf.

Coloquei ai uma pergunta, ve se consegue me ajudar, como leer um arquivo txt de dentro do Clipper.
OI Aqui é o Veio Modernel
Responder