[英]data file in horizontal format containing hidden characters
提供了我从未见过的格式的数据文件。 数据似乎不在一列中,而是在一长行中。 我可以在Notepad
打开文件并查看数据。 因此,数据似乎没有被加密。
当我在Notepad
打开数据文件时,当我猜测数据达到了Notepad
在单行中允许的最大字符数时,该行数据回绕到Notepad
窗口的左侧,然后该数据以新的形式继续行。
当我在Notepad
打开文件时,可能有10,000行数据。 这些行之一中的数据与其上方或下方的行中的数据不对齐。
以下是一些示例数据:
40001 1 5 GGGG 2998 HHHH SU111111 95 1.0 F1 4 1304 3 0 0
40001 1 5 GGGG 2998 HHHH SU111111 95 1.0 F1 4 0205 0 3 0
40001 1 5 GGGG 2998 HURG SU111111 95 1.0 F1 4 0805 0 2 0
40001 1 5 GGGG 2998 HHHH SU111111 95 1.0 F1 4 1205 0 2 0
40001 1 5 GGGG 2998 HHHH SU111111 95 1.0 F1 4 1505 0 0
40002 2 8 GGGG 2998 PPPP SK777777 -999 1.0 F3 4 2003 0 0
40002 2 8 GGGG 2998 PPPP SK777777 -999 1.0 F3 4 2303 2 0 0
40002 2 8 GGGG 2998 PPPP SK777777 -999 1.0 F3 4 2703 3 0 0
40002 2 8 GGGG 2998 PPPP SK777777 -999
请注意,当我在此处粘贴示例数据(代表Notepad
一行)时,各列“神奇地”对齐了。
我发现可以在Excel
打开数据文件,并且数据也对齐。 我确实需要在Excel
手动分配列边界。 而且Excel
不允许我分配或多或少的字符空间123以外的列边界。
下面是SAS
代码来读取数据文件,虽然这SAS
代码不能正常工作。 相反,我猜想这个SAS
代码会跳过一些数据行。 请注意,变量TT
覆盖了字符空间125-207,但是大多数行中只有120个字符。 在某些行中有超过120个字符。 我怀疑行之间的字符数差异是SAS无法正确读取此数据文件的原因。
option linesize = 210 ;
option pagesize = 30 ;
FILENAME myinput 'C:/Users/markm/simple SAS programs/mydata.new' ;
DATA mydata ;
INFILE myinput ;
INPUT
AA 2-9
BB 12-17
CC 18-22
DD $ 24-27
EE 30-33
FF $ 35-38
GG $ 40-47
HH 53-56
II 59-64
JJ $ 66-68
KK $ 70-71
LL 72-78
MM 79-85
NN $ 87-90
OO 91-95
PP 97-104
QQ 105-110
RR 112-120
SS $ 122-123
TT $ 125-207 ;
如果我使用右箭头键一次将光标移到第一行数据上的右一个字符,则必须按两次右箭头键才能移出Notepad
字符空间120。
所有这些都告诉我,数据文件中有隐藏的字符,用于标识一行数据的结尾。
我在Vim
打开了数据文件,希望看到这些隐藏的字符,但是什么也没看到。 打开文件时, Vim
确实正确对齐了列。 因此, Vim
必须看到这些隐藏的行尾字符。
我自己如何看到这些行尾字符? 我怀疑Vim
有一个选项可以显示隐藏的字符。
如何确定创建此数据文件的应用程序?
如何修改上述SAS
代码以正确读取此数据文件?
首先,请仔细检查您的LRECL。 您基本上丢失了一半的数据,这让我觉得您正在为每一行分两行阅读。 您显示207作为最大行大小,应该在默认的256 LRECL下,但是看到正确数字的1/2左右的数字会使我认为您在这里输入了错误。
接下来,确定您是否基本上每隔一行看到一条,或者看到的是前44k行然后突然停止。 如果是后者,则数据中有一个DOS EOF字符( 1A
),并且需要设置IGNOREDOSEOF
选项。 如果是前者,则可能是上述明显的LRECL问题,或者可能是由Unicode字符占用多个字节引起的非显而易见的LRECL问题(尝试LRECL=32767
看看是否可以解决;也将导致数据看起来每行的某个点很有趣),或者您遇到了一个奇怪的行终止符问题(尽管不一致)。
然后,假设EOL字符(或EOF?)存在问题,解决该问题的方法就是准确查看数据文件中的内容。
读取一个虚拟字符,然后将_infile_
行放入hex.
格式。 例如:
data test;
infile "d:\temp\utf8.txt" lrecl=256 RECFM=f;
input @1 x $1. @;
r = repeat('1234567890',8); *make this appropriate for your LS option in your log;
put r;
put _infile_;
put _infile_ hex512.;
stop; *we want to see just one line here;
run;
在那种情况下,我要读20行,并使用hex40.
,因为它必须是行长的两倍。 您可以保留长度( hex.
),但是如果这样做的话,您会得到一些非常长的行,其中包含大量的空白。 在您的情况下, lrecl=207
,您应该使用hex414.
从理论上讲(但是为了以防万一,可能要使您的lrecl 256
和hex512.
) 由于我们使用的是RECFM=F
,所以我们的想法是使RECFM=F
长于实际行的长度,因此您可以一次查看整个行。 (如果一行没有告诉您足够多的信息,请使用firstobs=
导航至下一行,并确认如果您的LRECL不完全适合该数据,则您不会跳到真实行的开头,但跳过256个字节的块)。
这将为您提供两个字符串,一个为“可见”字符串,这可能有助于查看SAS认为在什么位置,一个为可见字符串后面的十六进制代码。 假设您处于ASCII环境(不是DBCS或Unicode环境),则十六进制代码是每个字符2个值(一个字节= 2个十六进制值)。 请参阅此页面以获取ASCII码列表。
要查找的十六进制代码:
如果是Windows / Dos文档,则应该在行尾连续看到CRLF,即在207左右的位置连续一行0D0A
。如果是Unix文档,则在那里只能看到0A
。 如果这是Mac OS文档,则可能会看到LFCR或0A0D
。 为什么有人要保持一致。
您可能会看到一些东西,因为您得到了一些行。 (如果没有行终止符,SAS只会在第一行之后放弃。)您更有可能遇到以下问题之一:
00
或40
或20
个字符之间(比如,每一个角色都有一个),你有DBCS(双字节字符集)文件-这是什么,比如说,Windows操作系统的一个中国人或日本人复制的内容可能产生。 他们为每个字符使用两个字节,以表示其语言中的完整字符集。 但是即使存储英语documnet,它们仍会使用完整集-基本上只是添加一个填充字节,以使不兼容的程序(或未正确设置的程序,例如SAS)仍然具有合理的ASCII外观。 我的直觉是,您有一个DBCS文件,因为您大致跳过了每隔一行(尽管不完全是-并且您要跳过的更多内容-这对我来说有点奇怪)。
这是在gVim 7.4
如何查看隐藏的行尾字符的方法:
打开gVim 7.4
在gVim 7.4
打开数据文件
几次按escape
键以访问行编辑器。 注意按退出键
将不会在gVim 7.4
窗口上显示可见的结果。
在gVim 7.4
窗口底部键入:set list
按enter
键
完成上述操作后,我会在每行末尾看到一个蓝色的$
,我认为这是行尾隐藏字符。
也许如果我能够删除这些蓝色的$
符号并将结果保存为新名称,则SAS
可能能够读取该新数据文件。 如果我知道了这一点,我将发布更新。
编辑
我试图修改John Black在此处发布的说明以删除$,但是到目前为止还没有运气: 读取带有隐藏或不可见字符^ M的csv文件
我输入:%s/$//g
,将蓝色$
替换为黄色$
。 然后,我以新名称保存了文件,并使用gVim
打开了新文件。 但是当我键入:set list
,蓝色$
仍然存在于新文件中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.