导入带有行和列分隔符的扁平文件

3
我正在导入一个带有行和列分隔符的平面.txt文件。问题是行分隔符被用来减少文件大小,所以经常会跳过其他列。另一个问题是最长字符的长度未知,如果这个字符串被截断,则失去分隔符,整个结构将崩溃。
我正面临的问题的显式示例包括:
.txt文件
Var1'~'Var2'~'Var3'~'Var4'~'Var5'~'Var6'#@#@'
1'~''#@#@'
This is going to be a really long string as an example of a situation where the long string is very large and so the truncated string does not indicate a delimiter and we lose data '#@#@'
1'~' 2'~' 3'~' 4'~' 5'~' 6'#@#@'
1'~' 2'~' 3'~''#@#@'

我在尝试导入这些数据时遇到了很多问题,原因如下:
  1. 字符变量长度过长会使导入过程非常耗时,而我们不知道最长的字符变量长度,因此每次迭代都需要更多时间。

  2. 当结构意味着下一行可以在填充完所有列之前被标志时,我还没有找到处理列分隔符和行分隔符的方法,也就是说不能仅仅为行分隔符增加一个额外的列并删除它。

我已经尝试的 SAS 代码:

data want;
infile "file-location" dlmstr = "#@#@" dsd recfm = F lrecl=10000000000;
informat var $200.
input var $ @@;
run;

非常感谢您的经验和见解。

你发布的示例让人觉得你的行尾标记(我不喜欢把它们看作分隔符)包括一个实际的换行符。 - Tom
你的长字符串是否超过了数据集变量的32K最大限制? - Tom
我还没有检查,这个平面文件没有包含有关所包含的变量的最大长度的文档,我将包括文件的前两行。 - 78282219
我建议使用 LIST 命令查看文件。因此,要读取完整文件并查看最大行长度以及列出前5行,请运行以下代码:data _null_; infile "file" lrecl=1M; input; if _n_<=5 then list; run; - Tom
嗨,我希望数据提供者在自由文本中避免使用这些字符,但我认为它们会存在,因为有些名称是用其他语言(如日语)给出的。在这种情况下,SAS无法识别该字符,并将其导入为特殊字符。 - 78282219
显示剩余4条评论
1个回答

1
如果每行有一条记录,则只需在infile上使用missover或truncover选项;这将告诉SAS在到达EOL后停止读取。您必须处理奇怪的结束分隔符,因为如果尝试将其读入数字中,它将导致错误;您可能可以在预处理中尝试先删除该字符串。
data want;
  infile "yourfile-location" dlmstr="'~'" dsd lrecl=32767 truncover;
  input @;
  _infile_ = tranwrd(_infile_,"'#@#@'"," ");
  input var1 var2 var3 var4 var5 var6;
run;

如果以上方法出现问题,你写的方式也可以使用;基本上需要两次读取字符串,使用两种不同的分隔符选项,一次使用 "'#@#@'" 作为分隔符,另一次使用 "'~'" 作为分隔符。或者不需要两次读取,只需使用第一个分隔符读取一次,然后使用第二个分隔符解析即可。
data want;
  infile "yourfile-location" dlmstr="'#@#@'" dsd lrecl=32767;
  input @;
  array var[6] var1-var6;
  do _i = 1 to countc(_infile_,"~")+1;
    var[_i] = scan(_infile_,_i,"~");
  end;
run;

上述方法并不完美,因为它没有处理定界符周围的引号,但是根据细节,您可以找到解决方法——是否安全地在输入前完全压缩引号或者需要使用SUBSTR进行一些高级操作?关于字符串变量长度问题,最耗时的可能是写出文件。使用options compress=char;打开数据集压缩选项,假设您最终使用这些文件与此兼容(如果只是在其中运行SAS代码,则应该兼容)。然后它就不会尝试写出完整的变量长度。如果失败了,您可能需要重新考虑数据集结构,以避免出现此问题——不过要了解最佳解决方案,您需要提出一个单独的问题,并提供更多详细信息。

嗨Joe,谢谢你提供的信息,我正在阅读和探索truncover选项。我没有明确我的.txt文件的结构,我是从数据提供商那里收到的,长charvar列不是行中唯一存在的列,我的典型问题是char变量太长,导致截断,因此分隔符被截断并丢失。我希望truncover命令能解决这个问题? - 78282219
我目前正在测试您提出的解决方案,因此需要一些时间才能回复结果。 - 78282219
我收到了以下错误信息:lrecl超过了infile / infile = variable语句的最大允许长度(32,767 *) - 78282219
你需要对数据文件进行两次处理,第一次处理用于确定所需的列大小,以及对于非常长的文本,需要多少个32K长度的字符变量来包含数据(这将为代码生成(也称为宏)做准备)。第二次处理将使用你的代码生成器读取数据文件。 - Richard
谢谢,我会处理这个。 - 78282219
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接