为什么在应用 tranwrd 函数后最后一个字符被删除
Why is the last character getting removed after applying tranwrd function
我想替换我的 json 文件中的某些值(在此示例中,空值带有空引号。)我的解决方案工作正常,但出于某种神秘原因,[= 的最后一个字符19=] 文件被删除。无论最后一个字符如何,代码总是将其删除 - 我也尝试过使用另一个以大括号结尾的 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;
要查看内容如何变化,首先运行代码直到“数据null”语句并检查文件内容,然后运行最后一个声明。
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
,或其他相似(或使用正则表达式)。但重要的是输入和输出中需要匹配的字符数。如果你不能处理它(比如额外的 spaces 是有问题的)那么你只能“写一个新文件”。
第二,我寻找文件的结尾,然后故意在那里写下第二行。这避免了您在括号中遇到的问题,因为它避免了在括号之前写出 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
,因为这会使它 运行 快一点。请注意,我还删除了一个 space - 关于 SAS 如何执行此操作的一些奇怪的事情似乎从以下行中删除了一个 space 否则。不知道为什么,可能是 EOL 字符有些奇怪。
但再次强调 - 除非没有其他选择,否则不要执行任何操作。写一个新文件。
一个奇怪的事情是 PROC JSON 总是写入一个使用 LF 作为行尾字符的文本文件。
因此,如果添加以下注意事项,您可能能够覆盖文件:
- 在 INFILE 语句中使用 TERMSTR=LF。
- 在 INFILE 语句上使用 SHAREDBUFFERS。
- 用 TRANWRD() 函数替换相同字节数的字符串,并且不要将 space 作为该行的最后一个字符。
我还会搜索“: null”而不仅仅是 'null' 以降低替换文件中其他字符串中的这些字符的风险。
data _null_;
infile json SHAREBUFFERS termstr=lf ;
file json ;
input ;
_infile_ = tranwrd(_infile_,': null',': ""');
put _infile_;
run;
我想替换我的 json 文件中的某些值(在此示例中,空值带有空引号。)我的解决方案工作正常,但出于某种神秘原因,[= 的最后一个字符19=] 文件被删除。无论最后一个字符如何,代码总是将其删除 - 我也尝试过使用另一个以大括号结尾的 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;
要查看内容如何变化,首先运行代码直到“数据null”语句并检查文件内容,然后运行最后一个声明。
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
,或其他相似(或使用正则表达式)。但重要的是输入和输出中需要匹配的字符数。如果你不能处理它(比如额外的 spaces 是有问题的)那么你只能“写一个新文件”。
第二,我寻找文件的结尾,然后故意在那里写下第二行。这避免了您在括号中遇到的问题,因为它避免了在括号之前写出 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
,因为这会使它 运行 快一点。请注意,我还删除了一个 space - 关于 SAS 如何执行此操作的一些奇怪的事情似乎从以下行中删除了一个 space 否则。不知道为什么,可能是 EOL 字符有些奇怪。
但再次强调 - 除非没有其他选择,否则不要执行任何操作。写一个新文件。
一个奇怪的事情是 PROC JSON 总是写入一个使用 LF 作为行尾字符的文本文件。
因此,如果添加以下注意事项,您可能能够覆盖文件:
- 在 INFILE 语句中使用 TERMSTR=LF。
- 在 INFILE 语句上使用 SHAREDBUFFERS。
- 用 TRANWRD() 函数替换相同字节数的字符串,并且不要将 space 作为该行的最后一个字符。
我还会搜索“: null”而不仅仅是 'null' 以降低替换文件中其他字符串中的这些字符的风险。
data _null_;
infile json SHAREBUFFERS termstr=lf ;
file json ;
input ;
_infile_ = tranwrd(_infile_,': null',': ""');
put _infile_;
run;