【问题标题】:SAS: Set current folder to the folder containing the running programSAS:将当前文件夹设置为包含正在运行的程序的文件夹
【发布时间】:2013-01-24 23:33:05
【问题描述】:

我刚刚开始学习 SAS,因为我需要将它用于统计课程。对于本课程,该大学通过他们的虚拟机设置提供 SAS 9.2:我在他们的系统中进行预订,他们在其中一台服务器上生成 VM,然后我使用 Microsoft 的远程桌面客户端连接到 VM。每个会话生成和擦除虚拟机;每次都会重置设置,并且文件必须存储在我的客户端计算机上(可通过 UNC 路径在 VM 中访问)。

在此设置中,当我打开存储在笔记本电脑上的程序文件时,我只能通过硬编码完整路径或更新来访问随附的数据文件(每个都存储在与程序相同的文件夹中)每个会话开始时的“当前文件夹”设置。第一个是有问题的,因为这意味着该程序不会在其他任何地方运行 - 特别是当我通过电子邮件将其发送给教授时。第二个不方便,因为浏览到这个特定的 UNC 路径非常耗时,而且我已经必须浏览到相同的路径才能打开程序文件。

我想通过以编程方式将当前文件夹设置为包含该程序的文件夹来简化此操作。然后我可以打开文件并开始工作。我发现了一些getting the filename of the program filegetting the path to a fileref 和(超出链接限制)设置当前文件夹的示例,但我无法以正确的方式组合它们。请帮我把这些点连起来。

【问题讨论】:

    标签: sas


    【解决方案1】:

    要以编程方式从 SAS 更改 Windows 当前目录,您可以使用X 命令,这是使用“更改当前文件夹”对话框时真正发生的情况:

    x 'cd "\\computername\share name\folder"';
    

    您也可以使用SYSTEM 数据步进函数来执行此操作,我更喜欢这种方法,因为您会得到一个返回码(但当然需要更多的输入):

    data _null_;
       rc = system( 'cd "\\computername\share name\folder"' );
       if rc = 0 
          then putlog 'Command successful';
          else putlog 'Command failed';
    run;
    

    注意 UNC 路径用双引号括起来,如果路径包含空格,这是必需的。

    当然,这仍然需要您手动输入命令,但您可以将其添加到程序源代码中。如果您的 VM 环境允许您在服务器上保持某些永久存在,您可以将此命令保存到启动文件中。

    我想请教你的教授;如果您正在使用作为课程一部分提供给您的数据,您可能只需要发送源代码。另一方面,如果您将创建输出数据作为作业的一部分,您的教授可能希望您提供源代码和 SAS 数据集。他或她肯定会有一些程序。

    【讨论】:

    • 我希望它更改为包含代码的文件夹,而不是硬编码的路径。粘贴您的代码并对我的 UNC 路径进行硬编码失败。 X commandSYSTEM Function 似乎都在使用 Windows 命令行来更改当前目录,但 Windows 命令行拒绝使用 UNC 路径作为当前目录。您能否确认这适用于 UNC 路径?
    • 是的,它适用于 UNC 路径。如果您自己提交 X 命令 (x;),您的 SAS 会话将暂停,并且应打开一个 Windows 命令框,您可以在其中键入命令。使用它来发现正确的cd 命令来更改目录。键入 exit 以关闭该框并返回您的 SAS 会话。
    • 看起来它失败了,因为在粘贴路径的中间插入了换行符......现在它适用于硬编码路径,但不适用于计算路径。我的部分答案得到了正确的路径,但使用 rc = system( 'cd "&src"' ); 失败。我在这里错过了什么?
    • 另外,windows 命令框显示“CMD 不支持 UNC 路径作为当前目录”,所以我猜 SAS 不只是通过它运行每个命令。
    • cmd.exe 拒绝使用 UNC 路径作为当前目录,但 SAS 可以使用 UNC 路径作为当前文件夹。令人惊讶的是,SAS X 命令允许 cd 到 UNC 路径。似乎 SAS 不仅仅是生成 cmd.exe 来执行命令; the documentation 说“SAS 拦截更改目录命令,然后更改驱动器命令并更改其当前文件夹。” (我更喜欢具有单独调用而不是拦截命令的 API。)
    【解决方案2】:

    完整答案:

    SAS 的钝符号需要一些奇怪的分隔符摆弄才能将我的部分解决方案(查找路径)与@Bob Duell 的部分解决方案(设置当前文件夹)结合起来。似乎涉及两个关键规则:

    • &var 在双引号字符串 ("&var") 中展开,但在单引号字符串 ('&var') 中不展开
    • &var 中的引号在展开后不被视为分隔符

    因此解决方案是计算带引号的路径的字符串(其中引号是字符串的一部分),并在双引号参数中将其扩展为 X 或 SYSTEM:

    %let qsrc=%str(%")&src%str(%");
    X "cd &qsrc"
    

    不需要存储字符串,&src 和 &qsrc 都可以就地扩展,产生单语句解决方案:

    X "cd %str(%")%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))))%str(%")";
    

    这可以正确执行,但会破坏 GUI 中的语法着色。在一个字符串中,%str(%")"" 都扩展为 ",因此将 %str(%") 替换为 "" 都可以正确执行并且在 GUI 中正确着色:

    X "cd ""%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))))""";
    

    这继承了它仅在定义 SAS_EXECFILEPATH 和 SAS_EXECFILENAME 时才有效的限制,在 Windows GUI 编辑器中运行时就是这种情况。它还受到“cd”命令中的任何限制,SAS intercepts 而不是调用 Windows 命令行。我预计它会在包含引号的路径上失败。

    【讨论】:

    • 为什么不直接使用双双引号呢? x "cd ""&SRC""" ;
    • 因为在阅读您的评论之前我不知道这是一个选项。应该使用什么标准在""%str(%") 之间进行选择?有没有不等价的情况?
    • 显然"%str(%")" 混淆了 GUI 解析器,完全破坏了语法高亮,即使它正确执行。 "" 正确执行和语法高亮。
    • 您正在尝试将双引号传递给命令行(在这种情况下,因为您的文件路径中有空格)。但是您也需要解析宏变量,因此需要双双引号。 SAS 在 SYSTASK 文档中记录双双引号,support.sas.com/documentation/cdl/en/hostwin/63285/HTML/default/…
    • "" 似乎适用于任何字符串,而不仅仅是 SYSTASK。我找不到任何关于 SAS 字符串处理的概述(我发现最接近的是 macro quoting),但似乎至少有 3 种方法可以将双引号放入字符串中:"""%str(%")QUOTE(s)
    【解决方案3】:

    部分答案:从程序文件的文件名中获取包含文件夹的一种方法

    展开和记录步骤:

    /* Find PathName of folder containing program */
    %let FullName=%sysget(SAS_EXECFILEPATH);
    %put FullName: &FullName.;
    %let FullLen=%length(&FullName);
    %put FullLen: &FullLen.;
    %let BaseName=%sysget(SAS_EXECFILENAME);
    %put BaseName: &BaseName.;
    %let BaseLen=%length(&BaseName);
    %put BaseLen: &BaseLen.;
    %let PathLen=%eval(&FullLen.-&BaseLen.);
    %put PathLen: &PathLen.;
    %let PathName=%substr(&FullName,1,&PathLen);
    %put PathName: &PathName.;
    

    整合和静默:

    /* Find src folder */
    %let src=%substr(%sysget(SAS_EXECFILEPATH),1,%eval(%length(%sysget(SAS_EXECFILEPATH))-%length(%sysget(SAS_EXECFILENAME))));
    

    这仅在定义了 SAS_EXECFILEPATH 和 SAS_EXECFILENAME 时有效,具体何时定义尚不清楚。它在使用 Windows GUI 编辑器时确实有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 2016-01-01
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      相关资源
      最近更新 更多