工作中有時(shí)需要將外部文本信息導(dǎo)入SAS數(shù)據(jù)集中進(jìn)行處理,例如,將.log文檔導(dǎo)入SAS數(shù)據(jù)集進(jìn)行判斷輸出相關(guān)issue。這篇文章,介紹2種SAS讀入外部文檔數(shù)據(jù)的方法。
第一種方法,通過(guò)Fopen系列函數(shù)讀入;第二種方法,通過(guò)infile語(yǔ)句讀入。兩者相比,后者的代碼相對(duì)簡(jiǎn)潔,建議使用后者。
以以下路徑內(nèi)容進(jìn)行演示:

1. Fopen系列函數(shù)
在之前文章中介紹過(guò),通過(guò)Fopen系列函數(shù)獲取文件的末次修改時(shí)間的應(yīng)用,例如,SAS編程-宏:Source側(cè)與QC側(cè)程序運(yùn)行時(shí)間檢查。
關(guān)于讀入外部數(shù)據(jù),主要用到Fread、Fget這兩個(gè)函數(shù)。
Fread函數(shù)的作用是,從外部文件中讀入一條記錄到文件數(shù)據(jù)緩沖區(qū)(Reads a record from an external file into the FileData Buffer (FDB))。成功讀入一條記錄,函數(shù)返回0值;讀入失敗, 函數(shù)返回非0值。一個(gè)Fread函語(yǔ)句只能讀入一條記錄,如果想要讀取外部文檔的所有記錄,需要通過(guò)循環(huán)進(jìn)行處理。
Fget函數(shù)作用是,將數(shù)據(jù)從文件數(shù)據(jù)緩沖區(qū)(FDB)復(fù)制到一個(gè)變量中(Copies data from the File Data Buffer (FDB) into a variable)。成功復(fù)制,函數(shù)返回0值;如果沒(méi)有內(nèi)容復(fù)制,函數(shù)返回-1。
在介紹Fread函數(shù)的SAS官方文檔的中,就有利用這兩個(gè)函數(shù)讀入外部文檔的程序舉例。只不過(guò)示例使用的是宏程序,并將文檔內(nèi)容輸出到SAS日志中。(來(lái)源:SAS Help Center: FREAD Function)

為方便對(duì)文檔信息的處理,需將文檔內(nèi)容讀入SAS 數(shù)據(jù)集。以上程序不難在Data 步中實(shí)現(xiàn)。
%let filepath = E:\99_Test\Test\test5\Check_date.log;
data tmp;
*Get fileID;
fileres = filename("filepath", "&filepath.");
fileid = fopen("filepath");
length text $200;
do while ( fread(fileid) = 0 );
getres = fget(fileid, text, 200);
output;
end;
run;
以上程序并沒(méi)有使用Fclose函數(shù)注銷(xiāo)“文件ID”,也沒(méi)有使用filename函數(shù)取消取消文件路徑的關(guān)聯(lián)。這樣操作對(duì)輸出結(jié)果沒(méi)有影響,因?yàn)槌绦蜻\(yùn)行結(jié)束后,關(guān)聯(lián)會(huì)自動(dòng)移除、釋放。
其實(shí),以上代碼也無(wú)法使用這兩個(gè)函數(shù),因?yàn)檫@兩個(gè)函數(shù)在Data步驟只能以賦值語(yǔ)句的形式存在。由于Do while代碼塊中有Output語(yǔ)句,循環(huán)結(jié)束后賦值語(yǔ)句是失效的,所以無(wú)法實(shí)現(xiàn)。.
不過(guò),如果通過(guò)Do Until語(yǔ)句實(shí)現(xiàn)循環(huán),則可以在循環(huán)內(nèi)部進(jìn)行處理“釋放”相關(guān)內(nèi)容。最后一次循環(huán)記錄不會(huì)讀入外部文檔記錄,可以直接刪除。
%let filepath = E:\99_Test\Test\test5\Check_date.log;
data tmp;
*Get fileID;
fileres = filename("filepath", "&filepath.");
fileid = fopen("filepath");
*Read records;
length text $200;
readres = 0;
do until ( readres ne 0 );
getres = fget(fileid, text, 200);
readres = fread(fileid);
if readres ne 0 then do;
clores = fclose(fileid);
defile = filename("filepath", " ");
delete;
end;
output;
end;
run;
輸出結(jié)果如下:

2. infile語(yǔ)句
infile語(yǔ)句的作用是,指定要用INPUT語(yǔ)句讀入的外部文件(Specifies an external file to read with an INPUT statement)。
infile語(yǔ)句不像Fread系列函數(shù)那樣需要2步讀入,可以直接讀入外部文檔,簡(jiǎn)潔高效許多。
示例代碼如下:
%let filepath = E:\99_Test\Test\test5\Check_date.log;
data tmp2;
filepath = "&.filepath.";
infile dummy filevar = filepath end = lastrec truncover;
do while(not lastrec);
input text $200;
output;
end;
run;
filevar =選項(xiàng)指定保存外部文檔地址的變量,變量可以包含多個(gè)文件地址,input語(yǔ)句會(huì)一次進(jìn)行讀入。
如果讀入的記錄不足input語(yǔ)句設(shè)定的長(zhǎng)度時(shí),infile語(yǔ)句會(huì)默認(rèn)接著讀取下一條記錄。truncover選項(xiàng)使得讀入記錄長(zhǎng)度小于input語(yǔ)句設(shè)定長(zhǎng)度時(shí),會(huì)另開(kāi)一行讀取下一條記錄。
就不詳細(xì)介紹其他選項(xiàng)的含義了,具體參考SAS官方文檔SAS Help Center: INFILE Statement。
讀入結(jié)果如下,與前面結(jié)果一致。

總結(jié)
文章介紹了2種讀入外部文檔的方法,推薦使用infile語(yǔ)句,簡(jiǎn)潔高效。
感謝閱讀, 歡迎關(guān)注!
若有疑問(wèn),歡迎評(píng)論交流!