バッチ実行ログから不要な改ページ行を削除する
sasプログラムを右クリックしてバッチ実行すると、同じフォルダに
ログが生成されますが、どうしてもログに改ページ、ページ番号、
タイトル、日付が出てしまいます。
(ページ番号はNONUMBERと日付はNODATEオプションで消せますが。)
今回はこれを削除してみようと思います。
まず、以下をsasの構成ファイルに追記します。
構成ファイルは通常
"C:\Program Files\SASHome2\SASFoundation\9.4\nls\ja\sasv9.cfg"
これかと思います。
(うまく行かなければ、レジストリエディタを開いて、
バッチファイルで指定されているcfgファイルを
[HKEY_CLASSES_ROOT\SAS.Program.701\shell\SAS940\command]
あたりで探してください。
C:\Program Files\SASHome2\SASFoundation\9.4\sasv9.cfg
が指定されており、その中に
-config "C:\Program Files\SASHome2\SASFoundation\9.4\nls\ja\sasv9.cfg"
のようにcfg本体が指定されているはずです。
この本体に追記をしてください)
<プログラム>
-TERMSTMT=' options noxwait xsync; %let ls=%sysfunc(getoption(LINESIZE)); %let xfile=%sysfunc(getoption(LOG)); %let yfile=%sysfunc(pathname(work))\_tmp_.log; %let zfile=%sysfunc(pathname(work))_mod_.log; filename y "&yfile"; filename z "%sysfunc(pathname(work))_mod_.log"; x "copy ""&xfile"" ""&yfile"""; data _null_; retain posf; length logline $&ls. vl 8; infile y lrecl=&ls; input; file z; logline=_infile_; if logline="" then vl=0; else vl=length(logline); if _n_=1 then posf=0; pos=ANYCNTRL(logline); if pos^=1 and posf=0 then put logline $varying&ls.. vl; if posf=1 then posf=0; if pos =1 then posf=1; run; options noxsync; x "timeout /T 1 & copy ""&zfile"" ""&xfile"" & del ""&zfile"""; '
<解説>
- TERMSTMT
https://documentation.sas.com/?docsetId=lesysoptsref&docsetTarget=n0rjd82dx13qi7n1mw6rsljm7x1o.htm&docsetVersion=9.4&locale=en
SAS終了時に実行するステートメントを指定できます。最大2048文字。
- %let ls=%sysfunc(getoption(LINESIZE));
オプションのLINESIZEから、ログの1行あたりの文字数を取得します
改ページコードが入っている行は切れますが、最後に落とすので気にする必要はありません。
options noxwait xsync; x "copy ""&xfile"" ""&yfile""";
まず、バッチ実行時のログはSAS自身が掴んでいるので、そのままfilenameで読み取ったり
fcopyすることができません。そこで、Windowsに無理やりコピーさせます。
また、コピー完了を待つため、xsyncを指定します。
%let xfile=%sysfunc(getoption(LOG));
バッチ実行で生成されるログファイル名を取得します。
%let yfile=%sysfunc(pathname(work))\_tmp_.log;
ログのコピー先の一時ファイルとしてSASのworkライブラリ配下を指定します
%let zfile=%sysfunc(pathname(work))_mod_.log;
ログの一時ファイルを加工するファイルを指定します。(不要な行を削除する、等)
SASのworkライブラリの1つ上の階層に作成しているのは、意図的です。後で解説します。
infile y lrecl=&ls; input; file z;
一時ファイルから加工ファイルに出力します。
logline=_infile_;
_infile_で1行そのままを取得します。
input logline $と指定すると、デリミタで区切られちゃうので。
pos=ANYCNTRL(logline);
ANYCNTRLで制御文字の位置を取得します。
改ページが1文字目に出力されるので、それを検出するためです。
https://support.sas.com/documentation/cdl_alternate/ja/lefunctionsref/67960/HTML/default/p1mt339n2zhb33n1uejmw7470orv.htm
if pos^=1 and posf=0 then put logline $varying&ls.. vl;
そのまま「put logline」としてしまうと、前の空白が削除されてしまい、
「put logline $&LS..;」だと後ろが空白で埋められてしまうため、
$VARYINGwフォーマットを使って文字列長を指定して、必要な桁で出力します。
https://documentation.sas.com/?docsetId=leforinforref&docsetTarget=n0gyd5fptpa0ufn100pj7ghozy6i.htm&docsetVersion=9.4&locale=en
例えば、
data _null_;
a=' abc';
b=length(a);
put a;
put a $7.;
put a $varying7. b;
run;
の結果は以下のようになります。
abc↩ abc ↩ abc↩
1つ目はスペースが削除され、
2つ目は余計なスペースが追加され、
3つ目は変数長だけの長さになっていることが確認できます。
options noxsync; x "timeout /T 1 & copy ""&zfile"" ""&xfile"" & del ""&zfile""";
加工ログファイルを最初のログファイルに上書きします。
この時、noxsyncとすることで、以下のように処理が実行され、
SASがログを掴んでいるために失敗する、ということを回避します。
後はいつも通り右クリックからバッチ実行するだけ。
あら不思議、2ページめ以降の改ページ行が消えてスッキリ。
これでgit等での差分比較がしやすくなりますね。
(画像ではcfgに-NOSTIMERも追記しており、実行時処理時間も消しています。※)
※ NOSTIMERはINITSTMT内ではなく、普通にconfig記載でOKだったので修正しました