x statementの処理がおかしい件
x statement、通称xコマンドではWindowsのcmdにコマンドを指定して実行することができます。
例えばこんな感じ。
x 'cd c:\temp';/* カレントディレクトリをc:\tempに変更 */ x 'copy c:\users\xxx\documents\test.xlsx c:\temp\text.xlsx';/* excelファイルをコピー */ x 'c:\temp\text.xlsx';/* excelファイルを開く */
そして、パスに空白を含む場合は、ダブルクオーテーションで括る必要がある、というのは周知の事実かと思います。
上の2つ目の例で言えば(パスに空白が含まれているなら)以下のようにしなければなりません。
/* 結果は全部同じ。ダブルクオーテーション「"」を2つ並べると、「"」として処理される */ x 'copy "c:\users\xxx\documents\test.xlsx" "c:\temp\text.xlsx"'; x 'copy ""c:\users\xxx\documents\test.xlsx"" ""c:\temp\text.xlsx""'; x "copy ""c:\users\xxx\documents\test.xlsx"" ""c:\temp\text.xlsx""";
ただ、マクロ変数を使って
%let cmd="path1 & path2 & path3 & ..."; X "&cmd";
のようなことをやりたかったので上記の3つ目のように
-" ""path1"" & ""path2"" & ""path3"" & ..."
という文字列を作成していたのですが、xコマンドが正しく実行できたりできなかったり。
(ここは&をエスケープしてません、念の為)
で、検証のために作成したのが以下のコードです。
options noxwait noxsync;
/* 検証用ファイル */
x 'cd c:\temp';
filename a 'a.txt';
filename b 'b.txt';
filename c 'c.txt';
data _null_;
file a;
file b;
file c;
run;
filename a;
filename b;
filename c;
/* 1:OK */ x 'c.txt & ""a.txt"" & ""b.txt""';
/* 2:OK */ x 'c.txt & "a.txt" & "b.txt"';
/* 3:OK */ x "c.txt & ""a.txt"" & ""b.txt""";
/* 4:NG */ x ' ""a.txt"" & ""b.txt""';
/* 5:NG */ x ' "a.txt" & "b.txt"';
/* 6:NG */ x " ""a.txt"" & ""b.txt""";
/* 7:NG */ x """a.txt"" & ""b.txt""";
/* 8:OK */ x ' ""a.txt""';
/* 9:OK */ x ' "a.txt"';
/* 10:OK */ x " ""a.txt""";
/* 11:OK */ x """a.txt""";
上記をsasの拡張エディタに貼り付けて1行ずつ実行すると、テキストファイルが開くもの(OK)と開かないもの(NG)があります。
4,5,6はそれぞれ1,2,3から先頭の「c:\temp\c.txt & 」を抜いただけで動作しなくなります。
8,9,10はそれぞれ4,5,6から末尾の「 & ""c:\temp\b.txt""」を抜いただけで動作するようになります。
xコマンドで最初にダブルクオーテーションでくくったパスと&を渡すと、きちんと処理できないような…。
ちなみに、xコマンドとクオートを外した以下のコードは全てコマンドプロンプトできちんと動くんです。
c:\temp\c.txt & ""c:\temp\a.txt"" & ""c:\temp\b.txt"" c:\temp\c.txt & "c:\temp\a.txt" & "c:\temp\b.txt" ""c:\temp\a.txt"" & ""c:\temp\b.txt"" "c:\temp\a.txt" & "c:\temp\b.txt" ""c:\temp\a.txt"" "c:\temp\a.txt"
なんででしょう?