如何更简便地从文本文件固定行读取分号终止的多行数据?
在SAS中无需循环提取指定起始行到分号终止的数据块
我手里有控制数据,记录了多行数据块的起始行号,这些数据块以分号(;)作为终止标记。目前我用input #语句配合循环来定位数据块的终止位置,想问有没有更简便的输入指令,不用循环就能完成这个操作?
当前使用的代码示例
filename textdata temp; data _null_; file textdata; input; put _infile_; datalines4; 1 2 3 4 d e f g h i j k l m n o ; 4 5 6 7 p q r s ; ;;;; data marks; linenum = 5; output; linenum = 13; output; run; data extract; infile textdata; length block $150; do index = 1 by 1 while (not lastmark); set marks end=lastmark; input #linenum; do while (_infile_ ne ';'); block = catx(' ', block, _infile_); input; end; output; block = ''; end; stop; run;
数据块示例

优化方案
首先明确:SAS的INPUT语句没有直接实现「从指定行读取到分号终止」的单一指令——因为数据块的行数不固定,必须逐行检查终止标记,所以循环是这类场景下的必要操作,但我们可以简化代码结构,让逻辑更清晰简洁:
优化后的代码
filename textdata temp; data _null_; file textdata; input; put _infile_; datalines4; 1 2 3 4 d e f g h i j k l m n o ; 4 5 6 7 p q r s ; ;;;; data marks; linenum = 5; output; linenum = 13; output; run; data extract; set marks; infile textdata; length block $150; /* 定位到指定起始行,保留指针不换行 */ input #linenum @; /* 循环读取直到遇到分号终止 */ do until(_infile_ = ';'); block = catx(' ', block, _infile_); input @; end; output; run;
优化点说明
- 去掉原代码中外层的
do index循环,直接通过set marks逐个处理每个起始行号,代码结构更简洁 - 使用
input #linenum @;定位到目标行后,用do until(_infile_=';')替代原有的do while,逻辑更直观(直到满足终止条件才停止) - 用
input @;替代普通input,保留输入指针在当前行的末尾,避免不必要的换行跳转
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

