全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2590
推到 Plurk!
推到 Facebook!

如何处理txt文件?

答題得分者是:jow
nimo
一般會員


發表:5
回覆:9
積分:2
註冊:2007-11-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-11-15 02:11:53 IP:221.222.xxx.xxx 訂閱
各位大侠:

新手报到,请求帮助!

源文件内容如下:
dev name=1
dev ID=0000
host ID=001
***************************************************************
CA HT PT SS SA Info
***************************************************************
1 fscsi1 hdisk1 DA 1a active alive 0 0

dev name=2
dev ID=0000
host ID=002
***************************************************************
CA HT PT SS SA Info
***************************************************************
1 fscsi1 hdisk11 DB 1a active alive 0 0
2 fscsi2 hdisk2 DC 2a active alive 0 0

dev name=3
dev ID=0000
host ID=003
***************************************************************
CA HT PT SS SA Info
***************************************************************
1 fscsi1 hdisk21 DD 1a active alive 0 0
2 fscsi2 hdisk22 DE 2a active alive 0 0
3 fscsi3 hdisk3 DF 3a active alive 0 0

我希望得到的结果是:
insert into test values('1','0000','001','fscsi1','hdisk1','1a','','','','','','','','','');
insert into test values('2','0000','002','fscsi1','hdisk11','1a','fscsi2','hdisk2','2a','','','','','','');
insert into test values('3','0000','003','fscsi1','hdisk21','1a','fscsi2','hdisk22','2a','fscsi3','hdisk3','3a','','','');

如何实现呢?
非常感谢各位大侠的帮助!

谢谢!!
編輯記錄
taishyang 重新編輯於 2007-11-15 09:36:19, 註解 將[急]字拿掉‧
nimo 重新編輯於 2007-11-18 09:10:11, 註解 無‧
nimo 重新編輯於 2007-11-18 09:13:25, 註解 無‧
nimo 重新編輯於 2007-11-18 09:15:06, 註解 無‧
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-11-15 08:30:11 IP:220.134.xxx.xxx 訂閱
很規則的 txt 檔呀

1. 找 dev name= 取 後面的值(到換行符號)
2. 由下 1 row 開始找 dev ID= 取 後面的值(到換行符號)
3. 由下 1 row 開始找 host ID= 取 後面的值(到換行符號)
4. 由下 6 row 開始找 ___(前置 3 個空白) 將後面的資料以空白分割字串,再取要的部分
5. 由下 1 row 開始找 ___(前置 3 個空白) 若是則資料處理方法同 4. 若否,則回到 1 處理下一區塊

可能要用的 Pos() StringReplace() SubString(Delphi 不知道是用什麼取部分字串) 等函式,
按 txt 的規則一步一步去解。或是使用 regular expression 去找到想要的資料也行。


VMASK - ViewMove Automation Software KernelVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
nimo
一般會員


發表:5
回覆:9
積分:2
註冊:2007-11-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-11-15 10:59:38 IP:124.42.xxx.xxx 訂閱
dllee

非常感谢你的帮助!

我是刚接触Delphi,你能给我写个样例脚本吗,以便我更好的理解。

另外,这个TXT文件中,行数是不规则变化的,需要循环语句来实现,如何最终形成我所想要的结果呢(在第一封邮件中)?

非常感谢!

期待得到你的回复!


===================引 用 dllee 文 章===================
很規則的 txt 檔呀

1. 找 dev name= 取 後面的值(到換行符號)
2. 由下 1 row 開始找 dev ID= 取 後面的值(到換行符號)
3. 由下 1 row 開始找 host ID= 取 後面的值(到換行符號)
4. 由下 6 row 開始找 ___(前置 3 個空白) 將後面的資料以空白分割字串,再取要的部分
5. 由下 1 row 開始找 ___(前置 3 個空白) 若是則資料處理方法同 4. 若否,則回到 1 處理下一區塊

可能要用的 Pos() StringReplace() SubString(Delphi 不知道是用什麼取部分字串) 等函式,
按 txt 的規則一步一步去解。或是使用 regular expression 去找到想要的資料也行。


VMASK - ViewMove Automation Software KernelVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-11-15 13:06:26 IP:220.134.xxx.xxx 訂閱
早上給您的忘了結束條件,增訂如下:

1. 找 dev name= 取 後面的值(到換行符號), 若找不到 dev name= , 表示已找完, 結束讀取
2. 由下 1 row 開始找 dev ID= 取 後面的值(到換行符號)
3. 由下 1 row 開始找 host ID= 取 後面的值(到換行符號)
4. 由下 6 row 開始找 ___(前置 3 個空白) 將後面的資料以空白分割字串,再取要的部分
5. 由下 1 row 開始找 ___(前置 3 個空白) 若是則資料處理方法同 4. 若否,則回到 1 處理下一區塊

Delphi 我也是初學者,我只會使用 BCB5 開發程式... 真是 sorry 了。
如果是初學者,按以上的步驟,慢慢去實作,也是可以把功能實現的,就當作是練習吧。



VMASK - ViewMove Automation Software KernelVMIO-Server/SECS/GEMdllee's blogdllee's StatPlus
------
http://www.ViewMove.com
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-11-15 15:27:47 IP:210.66.xxx.xxx 訂閱

[code delphi]
unit fMain;

interface

uses
Forms, StdCtrls, Controls, Classes, SysUtils;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

function split(S: string; var X: TStringList): Boolean;
var
I: Integer;
begin
if not Assigned(X) then X := TStringList.Create;
X.Text := StringReplace(S,#32,#13,[rfReplaceAll,rfIgnoreCase]);
//去除空白列
for I := X.Count-1 downto 0 do
if Trim(X[I]) = '' then X.Delete(I);
Result := X <> nil;
end;

function Extract(S: string; Key: string): string; overload;
begin
Result := S;
if Length(Key) < Length(S) then
Result := Copy(S, Length(Key) 1, Length(S)-Length(Key));
end;

function Extract(S: string): string; overload;
var
X: TStringList;
begin
Result := '';
if split(S, X) and (X.Count = 9) then
Result := X[1] ',' X[2] ',' X[4];
FreeAndNil(X);
end;

var
I: Integer;
S, T: string;
L, M: TStringList;
begin
L := TStringList.Create;
try
L.LoadFromFile('D:\TEST.TXT');
M := TStringList.Create;
try
I := 0;
S := '';
while I < L.Count do
begin
if Pos('dev name=', L[I]) > 0 then
begin//New Item
if S <> '' then M.Add(S);
S := Extract(L[I], 'dev name=');
end
else if Pos('dev ID=' , L[I]) > 0 then S := S ',' Extract(L[I], 'dev ID=')
else if Pos('host ID=', L[I]) > 0 then S := S ',' Extract(L[I], 'host ID=')
else if Pos('fscsi' , L[I]) > 0 then
begin
T := Extract(L[I]);
if T <> '' then S := S ',' T;
end;
Inc(I);
end;
if S <> '' then M.Add(S);
ListBox1.Items.Text := M.Text;
finally
M.SaveToFile('D:\OUTPUT.TXT');//儲存到 D:\OUTPUT.TXT
FreeAndNil(M);
end;
finally
FreeAndNil(L);
end;
end;

[/code]

執行結果:(D:\OUTPUT.TXT的內容)

1,0000,001,fscsi1,hdisk1,1a
2,0000,002,fscsi1,hdisk11,1a,fscsi2,hdisk2,2a
3,0000,003,fscsi1,hdisk21,1a,fscsi2,hdisk22,2a,fscsi3,hdisk3,3a
編輯記錄
jow 重新編輯於 2007-11-15 15:30:33, 註解 無‧
jow 重新編輯於 2007-11-15 19:58:39, 註解 無‧
nimo
一般會員


發表:5
回覆:9
積分:2
註冊:2007-11-15

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-11-15 16:57:15 IP:124.42.xxx.xxx 訂閱
jow,
真的太谢谢你了!!!
我从中学到了很多,这对于我这个初学者而言,具有非常重要的意义!
另外,如果我想直接生成具有每行insert语句,同时,每个记录用“”双引号包括起来,该如何操作呢?
再次表示衷心的感谢!

jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-11-15 20:03:21 IP:123.193.xxx.xxx 訂閱
修改前一篇回應中的程式碼, 將結果儲存到 D:\OUTPUT.TXT

以下程式碼則將 D:\OUTPUT.TXT的內容再做一次處理
輸出的字串放置到 ListBox1 中.

[code delphi]
procedure TForm1.Button2Click(Sender: TObject);
const
VALUE_COUNT = 15;
var
I, J: Integer;
L, M: TStringList;
S: string;
begin
ListBox1.Clear;
if FileExists('D:\OUTPUT.TXT') then
begin
L := TStringList.Create;
try
L.LoadFromFile('D:\OUTPUT.TXT');
M := TStringList.Create;
try
for I := 0 to L.Count-1 do
begin
M.CommaText := L[I];
S := '''insert into test values(';
for J := 0 to VALUE_COUNT-1 do
begin
if J < M.Count then S := S '''' M[J] ''','
else S := S ''''',';
end;
S[Length(S)] := ' ';//去掉最後一個','
S := Trim(S) ')''';
ListBox1.Items.Add(S);
end;
finally
FreeAndNil(M);
end;
finally
FreeAndNil(L);
end;
end;
end;
[/code]

執行後ListBox1中的內容:

'insert into test values('1','0000','001','fscsi1','hdisk1','1a','','','','','','','','','')'
'insert into test values('2','0000','002','fscsi1','hdisk11','1a','fscsi2','hdisk2','2a','','','','','','')'
'insert into test values('3','0000','003','fscsi1','hdisk21','1a','fscsi2','hdisk22','2a','fscsi3','hdisk3','3a','','','')'

編輯記錄
jow 重新編輯於 2007-11-15 20:04:09, 註解 無‧
nimo
一般會員


發表:5
回覆:9
積分:2
註冊:2007-11-15

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-11-15 21:51:06 IP:222.130.xxx.xxx 訂閱
Jow,
问题已圆满解决,非常感谢!作为初学者,非常高兴能够得到你这么高水平的大侠指点!这对我今后的编程将会有很大的推动作用。
再次表示衷心的感谢!
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-11-15 23:46:58 IP:123.193.xxx.xxx 訂閱
修改輸出格式, 

insert into test values('1',‘host','0000','001','fscsi1','hdisk1','1a','','','','','','','','','');

並新增插入host_name(在Edit1輸入)到第二項目.




[code delphi]
procedure TForm1.Button2Click(Sender: TObject);
const
VALUE_COUNT = 16;//增加參數的個數
var
I, J: Integer;
L, M: TStringList;
S: string;
begin
ListBox1.Clear;
if FileExists('D:\OUTPUT.TXT') then
begin
L := TStringList.Create;
try
L.LoadFromFile('D:\OUTPUT.TXT');
M := TStringList.Create;
try
for I := 0 to L.Count-1 do
begin
M.CommaText := L[I];
M.Insert(1,Trim(Edit1.Text)); //插入Edit1.Text到第二個Item.
S := 'insert into test values('; //去除insert前面單引號.
for J := 0 to VALUE_COUNT-1 do
begin
if J < M.Count then S := S '''' M[J] ''','
else S := S ''''',';
end;
S[Length(S)] := ' '; //去掉最後一個','
S := Trim(S) ');'; //去除最後之單引號, 並加上 ';'.
ListBox1.Items.Add(S);
end;
ListBox1.Items.SaveToFile('D:\RESULT.TXT');
finally
FreeAndNil(M);
end;
finally
FreeAndNil(L);
end;
end;
end;
[/code]

輸出結果:

insert into test values('1','host1','0000','001','fscsi1','hdisk1','1a','','','','','','','','','');
insert into test values('2','host1','0000','002','fscsi1','hdisk11','1a','fscsi2','hdisk2','2a','','','','','','');
insert into test values('3','host1','0000','003','fscsi1','hdisk21','1a','fscsi2','hdisk22','2a','fscsi3','hdisk3','3a','','','');
編輯記錄
jow 重新編輯於 2007-11-16 00:22:19, 註解 無‧
jow
尊榮會員


發表:66
回覆:751
積分:1253
註冊:2002-03-13

發送簡訊給我
#10 引用回覆 回覆 發表時間:2007-11-17 08:54:48 IP:123.193.xxx.xxx 訂閱
將Button1與Button2的動作合併
去除中介檔案的儲存

最後的輸出在

//The final output
ListBox1.Items.Text := L2.Text;



[code delphi]
unit fMain;

interface
uses
Forms, StdCtrls, Controls, Classes, SysUtils;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
protected
function ProcessStep1(const FileName: string; var ret: TStringList): Boolean;
function ProcessStep2(L: TStringList; var ret: TStringList): Boolean;
function split(S: string; var X: TStringList): Boolean;
function Extract(S: string; Key: string): string; overload;
function Extract(S: string): string; overload;
end;

var
Form1: TForm1;
[/code]

[code delphi]
implementation
{$R *.dfm}
//------------------------------------------------------------------------------
procedure TForm1.Button1Click(Sender: TObject);
var
L1, L2: TStringList;
begin
L1 := TStringList.Create;
try
if ProcessStep1('D:\INPUT.TXT', L1) then
begin
L2 := TStringList.Create;
try
if ProcessStep2(L1, L2) then
begin
//The final output
ListBox1.Items.Text := L2.Text;
end;
finally
FreeAndNil(L2);
end;
end;
finally
FreeAndNil(L1);
end;
end;
//------------------------------------------------------------------------------
function TForm1.ProcessStep1(const FileName: string; var ret: TStringList): Boolean;
var
I: Integer;
L: TStringList;
S, T: string;
begin
if FileExists(FileName) then
begin
L := TStringList.Create;
try
L.LoadFromFile('D:\INPUT.TXT');
I := 0;
S := '';
while I < L.Count do
begin
if Pos('dev name=', L[I]) > 0 then
begin//New Item
if S <> '' then ret.Add(S);
S := Extract(L[I], 'dev name=');
end
else if Pos('dev ID=' , L[I]) > 0 then S := S ',' Extract(L[I], 'dev ID=')
else if Pos('host ID=', L[I]) > 0 then S := S ',' Extract(L[I], 'host ID=')
else if Pos('fscsi' , L[I]) > 0 then
begin
T := Extract(L[I]);
if T <> '' then S := S ',' T;
end;
Inc(I);
end;
if S <> '' then ret.Add(S);
finally
FreeAndNil(L);
end;
end;
Result := ret.Count > 0;

end;
//------------------------------------------------------------------------------
function TForm1.ProcessStep2(L: TStringList; var ret: TStringList): Boolean;
const
VALUE_COUNT = 16;//增加參數個數
var
I, J: Integer;
S: string;
M: TStringList;
begin
M := TStringList.Create;
try
for I := 0 to L.Count-1 do
begin
M.CommaText := L[I];
M.Insert(1,Trim(Edit1.Text)); //插入Edit1.Text到第二個Item.
S := 'insert into test values('; //去除insert前面單引號.
for J := 0 to VALUE_COUNT-1 do
begin
if J < M.Count then S := S '''' M[J] ''','
else S := S ''''',';
end;
S[Length(S)] := ' ';//去掉最後一個','
S := Trim(S) ');';//去除最後之單引號, 並加上 ';'.
ret.Add(S);
end;
finally
FreeAndNil(M);
end;
Result := ret.Count > 0;
end;
//------------------------------------------------------------------------------
function TForm1.split(S: string; var X: TStringList): Boolean;
var
I: Integer;
begin
if not Assigned(X) then X := TStringList.Create;
X.Text := StringReplace(S,#32,#13,[rfReplaceAll,rfIgnoreCase]);
//去除空白列
for I := X.Count-1 downto 0 do
if Trim(X[I]) = '' then X.Delete(I);
Result := X <> nil;
end;
//------------------------------------------------------------------------------
function TForm1.Extract(S: string; Key: string): string;
begin
Result := S;
if Length(Key) < Length(S) then
Result := Copy(S, Length(Key) 1, Length(S)-Length(Key));
end;
//------------------------------------------------------------------------------
function TForm1.Extract(S: string): string;
var
X: TStringList;
begin
Result := '';
if split(S, X) and (X.Count = 9) then
Result := X[1] ',' X[2] ',' X[4];
FreeAndNil(X);
end;
//------------------------------------------------------------------------------
end.
[/code]
編輯記錄
jow 重新編輯於 2007-11-17 08:59:36, 註解 無‧
系統時間:2024-05-06 16:41:18
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!