【问题标题】:Importing a flat file with row and column delimiters导入带有行和列分隔符的平面文件
【发布时间】:2018-10-16 14:15:04
【问题描述】:

我正在导入一个带有行和列分隔符的平面 .txt 文件。问题是行分隔符用于减小文件大小,因此通常会跳过其余列。另一个问题是最长字符的长度是未知的,因此,如果这个 char 字符串被截断,那么我们会丢失分隔符,整个结构就会崩溃。

我面临的问题的一个明确示例包括

.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;

非常感谢任何经验和见解。

【问题讨论】:

  • 您发布的示例使它看起来像您的行尾标记(我讨厌将这些视为分隔符)包含一个实际的换行符。
  • 对于数据集变量,您的长字符串是否超过 32K 最大值?
  • 我还没有检查,平面文件没有包含关于所包含变量的最大长度的文档,我将包含文件的前两行
  • 我推荐使用LIST 命令来查看文件。因此,要阅读完整文件并查看最大行长是多少,并列出前 5 行运行代码,如下所示:data _null_; infile "file" lrecl=1M; input; if _n_<=5 then list; run;
  • 有效数据是否包含任何这些单独的字符? ~'#@?如果不是,那么只需将它们全部用作分隔符。

标签: import sas delimiter flat-file sas-studio


【解决方案1】:

如果每行有一条记录,则只需在 infile 上使用 missovertruncover 选项;这将告诉 SAS 在达到 EOL 后停止读取。您只需要处理奇怪的结束分隔符,因为如果您尝试将其读入数字会导致错误;您可以尝试在预处理中首先删除字符串。

data want;
  infile "yourfile-location" dlmstr="'~'" dsd lrecl=32767 truncover;
  input @;
  _infile_ = tranwrd(_infile_,"'#@#@'"," ");
  input var1 var2 var3 var4 var5 var6;
run;

如果由于某种原因上述方法不起作用,您在那里编写它的方式也可以工作;基本上使用两个不同的分隔符选项在字符串中读取两次,一次使用“'#@#@'”dlmstr,然后使用“'~'”dlmstr。或者与其读两次,不如用第一次读一次,然后用第二次解析。

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 代码,则应该如此)。然后它不会尝试写出完整的可变长度。如果失败,您可能需要重新考虑您的数据集结构以避免出现此问题 - 您需要提出一个包含更多详细信息的单独问题,才能找到最佳解决方案。

【讨论】:

  • 嗨,乔,感谢您提供的信息,我目前正在阅读和探索 trunco​​ver 选项。我没有明确 .txt 文件的结构,我是从数据提供者那里收到的,而且长 charvar 列不是行中唯一存在的,我的典型问题是 char 变量太长以至于它截断,因此分隔符被截断并丢失。我希望 trunco​​ver 命令能解决这个问题?
  • 我目前正在测试您提出的解决方案,因此需要一些时间来回复结果
  • 我收到以下错误消息 lrecl 超出了 infile / infile = variable 语句的最大允许长度 (32,767*)
  • 您必须通过 2 遍数据文件,第 1 遍来确定所需的列大小,对于非常长的文本,包含数据所需的 32K 长度字符变量的数量(这将是代码生成(又名宏)的准备工作)。第二遍将使用您的代码生成读取数据文件。
  • 谢谢,我会解决的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2013-12-19
相关资源
最近更新 更多