为啥应用 tranwrd 函数后最后一个字符被删除
Posted
技术标签:
【中文标题】为啥应用 tranwrd 函数后最后一个字符被删除【英文标题】:Why is the last character getting removed after applying tranwrd function为什么应用 tranwrd 函数后最后一个字符被删除 【发布时间】:2022-01-14 09:06:25 【问题描述】:我想替换我的 json 文件中的某些值(在此示例中,空值带有空引号。)我的解决方案工作正常,但由于某种神秘的原因,json 文件的最后一个字符被删除。不管最后一个字符是什么,代码总是会删除它——我也尝试过使用不同的以花括号结尾的 json 文件。
这是什么原因造成的,更重要的是我该如何预防?
data testdata_;
input var1 var2 var3;
format _all_ commax10.1;
datalines;
3.1582 0.3 1.8
21 . .
1.2 4.5 6.4
;
proc json out = 'G:\test.json' pretty fmtnumeric nosastags keys;
export testdata_;
run;
data _null_;
infile 'G:\test.json';
file 'G:\test.json';
input;
_infile_ = tranwrd(_infile_,'null','""');
put _infile_ ;
run;
要查看内容如何变化,首先运行代码直到“data null”语句并检查文件内容,然后运行最后一条语句。
【问题讨论】:
写一个新文件。更改 FILE 语句以使用不同的文件名。 【参考方案1】:Data _null_
是否正确;不要写入同一个文件。 SAS 提供了这个选项,但在现代,它几乎总是是错误的答案,因为 SAS 对此提供了支持,而且存储足够便宜和快速。
在这种情况下,它看起来是一个相对简单的修复,但您可能应该按照建议进行操作并写入一个新文件 - 会有其他问题。
data testdata_;
input var1 var2 var3;
format _all_ commax10.1;
datalines;
3.1582 0.3 1.8
21 . .
1.2 4.5 6.4
;
proc json out = 'H:\temp\test.json' pretty fmtnumeric nosastags keys;
export testdata_;
run;
data _null_;
infile 'H:\temp\test.json' end=eof;
file 'H:\temp\test.json';
input @;
putlog _infile_;
_infile_ = tranwrd(_infile_,'null','"" ');
len = length(_infile_);
put _infile_ ;
if eof then put _infile_;
run;
有两个变化。一、我在tranwrd中使用'"" '
而不是'""'
;那是因为否则你会在添加新行时得到稍微奇怪的结果。如果您的 JSON 解析器不喜欢 "" ,
,那么您可能想要两个 tranwrd
,一个用于 null,
,一个用于 null
,或类似的东西(或使用正则表达式)。但重要的是输入和输出中需要匹配的字符数。如果你不能处理(比如多余的空格有问题),那么你就剩下“写一个新文件”了。
二,我寻找文件的结尾,然后故意在那里写出第二行。这避免了您在使用括号时遇到的问题,因为它避免了在括号之前写出 EOF。我不是 100% 确定我知道你为什么需要它 - 但你知道。
另一个可能更有意义的选择是只写有括号的行。
data _null_;
infile 'H:\temp\test.json' sharebuffers;
file 'H:\temp\test.json';
input @;
putlog _infile_;
if find(_infile_,'null') then do;
_infile_ = tranwrd(_infile_,'null','"" ');
put _infile_;
end;
run;
我添加了sharebuffers
,因为这应该使它运行得更快一些。请注意,我还删除了一个空格 - SAS 这样做的方式有些奇怪,否则会从下一行中删除一个空格。不知道为什么,可能 EOL 字符有些奇怪。
但是,除非没有其他选择,否则不要这样做。写一个新文件。
【讨论】:
【参考方案2】:一个奇怪的事情是,PROC JSON 总是写一个使用 LF 作为行尾字符的文本文件。
因此,如果添加这些警告,您也许可以覆盖文件:
-
在 INFILE 语句中使用 TERMSTR=LF。
在 INFILE 语句中使用 SHAREDBUFFERS。
使用 TRANWRD() 函数替换具有相同字节数的字符串,并且不要将空格作为行的最后一个字符。
我还会搜索 ':null' 而不仅仅是 'null' 以降低替换文件中其他字符串中的这些字符的风险。
data _null_;
infile json SHAREBUFFERS termstr=lf ;
file json ;
input ;
_infile_ = tranwrd(_infile_,': null',': ""');
put _infile_;
run;
【讨论】:
我认为这是这里的具体问题 -0D0A
被写出,并覆盖 0A5D
(括号为 5D
)。以上是关于为啥应用 tranwrd 函数后最后一个字符被删除的主要内容,如果未能解决你的问题,请参考以下文章