You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SAS中将FTP路径传入%get_files宏以获取文件名

Solution for SAS Macro to List FTP Files

Got it, let's figure out how to adapt your %get_files macro to work with FTP paths. The core issue here is that your existing macro is built to interact with local file systems, but FTP requires SAS to establish a remote connection first using its dedicated FTP engine. Here's a step-by-step optimized approach:

1. Understand SAS FTP Basics

SAS uses the FILENAME statement with the FTP engine to connect to remote servers. The LIST flag tells SAS to retrieve the directory listing instead of transferring files. You may also need the PASSIVE option if your network uses a firewall (common in most environments).

2. Extend Your Macro to Support FTP

Instead of rewriting from scratch, we can add an FTP-specific branch to your existing macro. This way it works for both local and remote paths. Here's a revised version:

%macro get_files(location, type=local, ftp_host=, ftp_user=, ftp_pass=);
    %local fileref rc;

    /* Handle FTP paths */
    %if &type. = ftp %then %do;
        /* Establish FTP connection and get directory list */
        filename ftp_dir ftp "&location." 
            host="&ftp_host."
            user="&ftp_user."
            pass="&ftp_pass."
            list
            passive; /* Add this if behind a firewall */

        /* Parse the FTP directory listing */
        data file_list;
            length filename $256;
            infile ftp_dir truncover;
            input line $500.;
            
            /* Adjust this parsing logic to match your FTP server's output format */
            /* Example for UNIX-style listings (e.g. "-rw-r--r-- 1 user group 4096 Aug 15 14:32 file.txt") */
            if prxmatch('/\d{2}:\d{2} \S+$/', line) or prxmatch('/\d{4} \S+$/', line) then do;
                filename = scan(line, -1, ' ');
                /* Skip parent directory (..) if needed */
                if filename not in ('.', '..') then output;
            end;
        run;

        /* Clean up the FTP connection */
        rc = filename('ftp_dir', '');
    %end;

    /* Handle local paths (your original logic) */
    %else %do;
        data file_list;
            length filename $256;
            rc = filename('local_dir', "&location.");
            dir_id = dopen('local_dir');
            
            if dir_id > 0 then do;
                do i = 1 to dnum(dir_id);
                    filename = dread(dir_id, i);
                    output;
                end;
                rc = dclose(dir_id);
            end;
            rc = filename('local_dir', '');
            keep filename;
        run;
    %end;
%mend get_files;

Key Notes for the FTP Branch:

  • Parsing Logic: FTP servers return directory listings in different formats (UNIX vs. Windows). The regex above handles common UNIX-style outputs—adjust it if your server uses a different format (e.g., Windows FTP might show dates as MM/DD/YYYY).
  • Security: Avoid hardcoding passwords in plaintext. Use PROC PWENCODE to encrypt your password, then reference the encrypted string in the macro:
    proc pwencode in='your_plain_password' out=encrypted_pass;
    run;
    
    Then pass &encrypted_pass. as the ftp_pass parameter.
  • Passive Mode: The passive option is critical if you're working behind a corporate firewall—without it, SAS might fail to establish the data connection for the directory list.

3. How to Use the Extended Macro

For FTP paths:

%get_files(
    location='/remote/ftp/path',
    type=ftp,
    ftp_host='your.ftp.server.com',
    ftp_user='your_username',
    ftp_pass='your_encrypted_password'
);

For local paths (original usage):

%get_files(location='/local/directory/path');

4. Alternative: Download FTP List to Local First

If you prefer not to modify your macro, you can first save the FTP directory listing to a local temp file, then use your existing macro to parse that local file:

/* Retrieve FTP list to local temp file */
filename ftp_list ftp '/' 
    host='your.ftp.server.com'
    user='your_username'
    pass='your_password'
    list
    passive;
filename temp_list '/tmp/ftp_directory_list.txt';

data _null_;
    infile ftp_list;
    file temp_list;
    input;
    put _infile_;
run;

/* Now parse the local temp file with your original macro (adjust as needed) */
data file_list;
    infile temp_list truncover;
    input line $500.;
    filename = scan(line, -1, ' ');
    if filename not in ('.', '..') then output;
run;

This approach is simpler but adds an extra file-write step.

内容的提问来源于stack exchange,提问作者Mixer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:18:24