Sas 在某些字段中读取带有换行符的csv,termstr=crlf不';行不通
我有一个csv文件,其中有用户输入的注释,偶尔以换行符结尾。这会在使用Sas 在某些字段中读取带有换行符的csv,termstr=crlf不';行不通,sas,Sas,我有一个csv文件,其中有用户输入的注释,偶尔以换行符结尾。这会在使用infle时导致错误,并导致变量顺序错误的行 我试过termstr=crlf或cr或lf。使用lf或crlf时,我读取到的观察值为零,而使用cr时,我得到的错误与我忽略它一样 如果我在excel中打开该文件并执行替换ctrl-j(例如),它就解决了问题,并且数据可以完美地读入 该文件来自BackEnd,原始数据来自智能手机 编辑:我解决了这个问题,并以以下内容结束 data _null_; infile 'test.csv
infle
时导致错误,并导致变量顺序错误的行
我试过termstr=crlf
或cr
或lf
。使用lf
或crlf
时,我读取到的观察值为零,而使用cr
时,我得到的错误与我忽略它一样
如果我在excel中打开该文件并执行替换ctrl-j(例如),它就解决了问题,并且数据可以完美地读入
该文件来自BackEnd,原始数据来自智能手机
编辑:我解决了这个问题,并以以下内容结束
data _null_;
infile 'test.csv' recfm=n lrecl=50000;
file 'testout.csv' recfm=n;
input a $char1.;
if a = '"' then do;
d+1;
if d = 2 then d = 0;
end;
if a = "," and d = 0 then do;
c+1;
end;
if a = '0A'x then do;
if c = 2 then do;
c = 0;
put '0A'x;
end;
end;
else put a $char1.;
run;
第一个条件跟踪我看到的分隔符(
,
)是真正的分隔符还是仅仅在字符串中,第二个条件统计我迄今为止看到的变量数。最后一个条件删除所有lf
,但在我看到正确数量的变量(c=2
)之后除外。您可以尝试使用misshover或truncover infle选项,以防SAS读取超过换行符缺失时的行尾导致错误
也可以在infle语句之后、input语句之前,从缓冲区自动变量中压缩换行符。例如:
data test;
infile "myfile.csv";
* Hold the current line being read;
input @;
* Compress out the LF -- you could also try this with CR and CRLF;
_infile_ = compress(_infile_,'0A'x);
* Your input statement should now read the cleaned up buffer;
input myvar ;
run;
如果您的数据有正常的CRLF终止字符串,这将起作用。这是用来读取在Excel中创建的文件中有3列,并且ALT+进入在中间的字符串在几个地方。
data test;
infile "c:\temp\newlines.csv" termstr=crlf dlm=',' dsd;
format stuff stuff2 stuff3 $100.;
input
stuff $
stuff2 $
stuff3 $
;
run;
如果最后只有stuff
有一个值(前100个字符或诸如此类),那么您的数据中可能没有CRLF。如果它来自第三方服务(就像你的服务一样),我首先会去那个服务或应用程序,看看你有什么选择
使用recfmt=V
并查看十六进制输出,您总是可以看到输入的内容
data test2;
infile "c:\temp\newlines.csv" recfm=f ls=20 end=eof flowover;
format indata $20.;
do until (eof);
input @1 indata $20.;
put indata= hex.;
put indata=;
end;
stop;
run;
一次可以提供20个字符,十六进制和标准ASCII表示。CR为“0D”,LF为“0A”。所以,找到你的第一个正常的行尾[目测一下,在最后一列中找到应该是什么],看看后面是否有0D0A。如果没有,那么您就没有CRLF终止符,这是一个问题
请注意,当您在Excel中打开它时,Excel无疑会为您添加它们,因此这无助于解决此问题-您必须查看原始文件
例如,上面的“我的垃圾数据文件”为前2个输入过程生成:
indata=73747566662C224D6F72650A5374756666222C4D
indata=stuff,"More Stuff",M
indata=792073747566660D0A6F6E652C74776F2C746872
indata=y stuff one,two,thr
在第一行,“更多”和“东西”之间有一个0A。[更多是4D6F7265,资料是5374756666]。这都在一行上,原始CSV是
stuff, "More Stuff", My stuff
one,two,three
除了使用换行符,而不是“更多内容”中的空格
在第二行中,“stuff”(7374756666,与上面相同,但小写s是73而不是53)后面有0D0A。这是CR+LF,正常的线路终止符
如果原始文件中没有行终止符,则可能需要使用变量输入读入。您可以使用dlm=','
但是recfm=v
,这允许您一次只读取一个分隔位
data test3;
infile "c:\temp\newlines.csv" recfm=v dlm=',' dsd end=eof flowover termstr=crlf;
format stuff stuff2 stuff3 $100.;
input stuff $ @;
input stuff2 $ @;
input stuff3 $ @;
run;
它使用
recfm=v
基本上不担心缺少线端终止符。对于这个问题还有许多其他的解决方案(recfm=n
,例如,读取流输入是另一个很好的解决方案)。一旦您对特定问题有了更多了解,请搜索Google/etc以获取更多详细信息。替换输入行中的结束行字符,其中字符串的分隔符出现了奇数次。您的SAS在哪个操作系统中?线路真的被CRLF终止了吗?这是Windows。我怎么说呢?它们绝对是新行。看十六进制。很多文本编辑器都有这个选项。谢谢。查看我的文件,我认为问题是<代码> LF既是我的结束行终止符,又是一些条目中间的断线。因此,termstr=lf
经常中断。我无法让您的任何解决方案发挥作用,在我描述的情况下,其中一个解决方案是否可能发挥作用?(在记事本++中查看的具有相同问题的虚拟文件,请参见此处)