SAS从一行中读取多条记录而无需换行CRLF

Posted

技术标签:

【中文标题】SAS从一行中读取多条记录而无需换行CRLF【英文标题】:SAS Reading multiple records from one line without Line Feed CRLF 【发布时间】:2014-01-16 01:16:19 【问题描述】:

我只有 1 行没有换行(CRLF CRLF),换行是一个 4 个字符的字符串,在这个例子中是“@A$3”我现在不需要 dlm,我需要从一个外部文件(/files/Example.txt)

JOSH 30JUL1984 1011 SPANISH@A$3RACHEL 29OCT1986 1013 MATH@A$3JOHNATHAN 05JAN1985 1015 chemistry

我需要将此行分成3行:

JOSH 30JUL1984 1011 SPANISH
RACHEL 29OCT1986 1013 MATH
JOHNATHAN 05JAN1985 1015 chemistry

我如何在 SAS 中做到这一点?

*已添加:您的解决方案正在使用此示例,但我有一个问题,包含超过该行允许的最大长度(32,767 字节)的行,

例如,上述练习中的这一行包含 5,000 条记录。

有可能吗?

【问题讨论】:

如果您只是想从一行文本中读取多条记录,请将“@@”附加到“输入”行的末尾,例如:input column1 255。@ @; 【参考方案1】:

infile 语句中使用DLMSTR= 选项——这将指定“@A$3”作为分隔符。然后在输入语句上使用@@ 告诉 SAS 在同一行查找更多记录。

data test;
infile "/files/Example.txt" dsd dlmstr='@A$3';
informat var $255.;
input var $ @@;
run;

通过您的示例,您将获得一个包含 3 条记录的数据集,其中 1 个变量包含您要查找的字符串。

根据需要调整 var 的长度。

【讨论】:

我们遇到了DLMSTR= 的问题,它没有将@A$3@A$3 识别为缺失值。那是在 SAS 9.2 中,现在可能已经修复了。 @DejanPeretin 我也曾想过使用DLMSTR= 来指定多字符分隔符,但它可能不适用于所有版本。因此,需要使用单字符定界符的替代转换方法。我认为 DomPazz 的 DLMSTR= 应该适用于 SAS 9.2 及更高版本,因为它是在 9.2 中引入的,但对于 9.1.3 及更早版本,它会作为错误返回。 发现:如果文件中有连续的分隔符字符串指示缺失值,则 DLMSTR= 选项将无法正确读取文件,直到 SAS 9.3。来源:support.sas.com/kb/33/385.html【参考方案2】:

你可以这样做:

先将文件导入为单行(一定要调整长度):

DATA WORK.IMPORTED_DATA;
INFILE "/files/Example.txt" TRUNCOVER;
LENGTH Column1 $ 255;
INPUT @1 Column1  $255.;
RUN;

然后使用数据步骤将导入的数据解析为变量:

data result (keep=var1-var4);
set  WORK.IMPORTED_DATA;

delim = '@A$3';
end = 1;
begin = 1;
do while (end > 0);

    end = find(Column1, delim, begin);
    row = substr(Column1, begin, end - begin);

    var1 = scan(row, 1);
    var2 = scan(row, 2);
    var3 = scan(row, 3);
    var4 = scan(row, 4);

    begin = end + length(delim);
    output;
end;
run;

【讨论】:

【参考方案3】:

通过将@A$3 视为多字符分隔符,在数据步骤中尝试此操作:

data want (keep=subject);
    infile 'C:\sasdata\test.txt';
    input;                                                     
    length line $4500  subject $80;
    line=tranwrd(_infile_,"@A$3",'!');         

    do i=1 by 1 while (scan(line,i,'!') ^= ' ');
        subject=scan(line,i,'!');                       
        output;
    end;
run;

_infile_ 给出在data 步骤中正在读取的当前行。我将多字符分隔符@A$2 转换为单字符分隔符。 tranwrd() 可以替换字符串中的子字符串。然后在scan() 函数中使用分隔符。

此外,如果您想将值分解为单独的变量,只需再扫描一些即可。例如。将B = scan(subject,2); 之类的内容放入do 循环和data want (keep= A B C D);。干杯。

【讨论】:

以上是关于SAS从一行中读取多条记录而无需换行CRLF的主要内容,如果未能解决你的问题,请参考以下文章

C语言中回车符和回车换行符有啥区别

sql带条件多条数据合并为一条数据并换行

git warning: LF will be replaced by CRLF

git 处理 crlf rf

如何从标准输入读取一行,阻塞直到找到换行符?

在 IRC 消息中插入换行符