将值替换为空值/null
Replace values with nothing / null
我有一个包含分隔符(如#RT#、#LT#、#BC# 等)的文本文件需要删除。
例如:-
原文:欠税:#RT#$3000
修正版:欠税:$3000
替换为 SPACES 显然不起作用,因为它会放入空格 - 因为这将是计算机读取的文件 - 它需要准确 - 只有 nothing/null 可以。
有什么想法吗?
以上是数据的代表性样本...只是其中包含#RT# 和#LT# 的随机数据段。当前,使用 REPLACING with SPACES。但我需要像上面的例子一样完全删除它。不能 post 密码到明天,因为我在路上。
INSPECT yourtext REPLACING BY SPACES
留空格。 INSPECT yourtext REPLACING BY ""
是不允许的(两者的长度必须相同,或者替换标识符是一个比喻常量:SPACE[S]、ZERO[S|ES] 或 QUOTE[S])- 很好如果您尝试此操作,编译器将输出一条可以理解的消息。
这只剩下 3 个选项:
不要使用 COBOL(如果您不想对文本文件做任何其他事情,这将是第一个选项)而是系统调用,例如 sed -e 's/#RT#//g' yourfile > yourtarget
,根据您使用的 COBOL 运行时(在问题中添加此信息总是一个好主意!)您可以通过 COBOL 使用 CALL "SYSTEM" USING external-command
.
启动该过程
READ
数据,使用特定于您的运行时的扩展来翻译它(例如使用 GnuCOBOL:MOVE FUNCTION SUBSTITUTE (yourtext, '#RT#', '', '#LT#'. '') TO translated-text
)- 可能是 FUNCTION
,系统库 CALL
- 和 WRITE
数据返回。
古老的 COBOL 方法 - 见下文。
因为问题不是关于读取数据或写回数据,所以这只是替换部分:
选项 a): UNSTRING 语句
MOVE 0 TO t1, t2, t3, t4
UNSTRING yourtext
DELIMITED BY ALL '#RT#' OR
ALL '#LT#' OR
...
INTO target-1 COUNT IN t1
target-2 COUNT IN t2
target-3 COUNT IN t3
target-4 COUNT IN t4
...
END-UNSTRING
MOVE SPACES TO translated-text
STRING target-1 (1:t1)
target-2 (1:t2)
target-2 (1:t2)
target-2 (1:t2)
...
DELIMITED BY SIZE INTO translated-text
END-STRING
选项 b) 带有两个指针的简单 PERFORM VARYING
,结合简单的 IF
语句。
*> you may get more performance if you `REDEFINE` source-text as a `PIC X OCCURS length-of-text TIMES` - but I find this one more better to read and it shouldn't consume much more time...
MOVE 0 TO target-pointer
PERFORM VARYING source-pointer
FROM 1 BY 1
UNTIL source-pointer > length-of-text
IF source-text (source-pointer:1) = '#'
*> a very good optimizer would calculate the constant on the
*> right side, you may write it directly
IF source-pointer + 4 > length-of-text
ADD 1 TO target-pointer
MOVE source-text (source-pointer:)
TO target-text (target-pointer:)
EXIT PERFORM
END-IF
IF source-text (source-pointer:4) = '#RT#' OR '#LT#' OR ...
ADD 4 TO source-pointer
EXIT PERFORM CYCLE
END-IF
END-IF
ADD 1 TO target-pointer
MOVE source-text (source-pointer:1)
TO target-text (target-pointer:1)
END-PERFORM
我有一个包含分隔符(如#RT#、#LT#、#BC# 等)的文本文件需要删除。
例如:-
原文:欠税:#RT#$3000
修正版:欠税:$3000
替换为 SPACES 显然不起作用,因为它会放入空格 - 因为这将是计算机读取的文件 - 它需要准确 - 只有 nothing/null 可以。
有什么想法吗?
以上是数据的代表性样本...只是其中包含#RT# 和#LT# 的随机数据段。当前,使用 REPLACING with SPACES。但我需要像上面的例子一样完全删除它。不能 post 密码到明天,因为我在路上。
INSPECT yourtext REPLACING BY SPACES
留空格。 INSPECT yourtext REPLACING BY ""
是不允许的(两者的长度必须相同,或者替换标识符是一个比喻常量:SPACE[S]、ZERO[S|ES] 或 QUOTE[S])- 很好如果您尝试此操作,编译器将输出一条可以理解的消息。
这只剩下 3 个选项:
不要使用 COBOL(如果您不想对文本文件做任何其他事情,这将是第一个选项)而是系统调用,例如
sed -e 's/#RT#//g' yourfile > yourtarget
,根据您使用的 COBOL 运行时(在问题中添加此信息总是一个好主意!)您可以通过 COBOL 使用CALL "SYSTEM" USING external-command
. 启动该过程
READ
数据,使用特定于您的运行时的扩展来翻译它(例如使用 GnuCOBOL:MOVE FUNCTION SUBSTITUTE (yourtext, '#RT#', '', '#LT#'. '') TO translated-text
)- 可能是FUNCTION
,系统库CALL
- 和WRITE
数据返回。古老的 COBOL 方法 - 见下文。
因为问题不是关于读取数据或写回数据,所以这只是替换部分:
选项 a): UNSTRING 语句
MOVE 0 TO t1, t2, t3, t4
UNSTRING yourtext
DELIMITED BY ALL '#RT#' OR
ALL '#LT#' OR
...
INTO target-1 COUNT IN t1
target-2 COUNT IN t2
target-3 COUNT IN t3
target-4 COUNT IN t4
...
END-UNSTRING
MOVE SPACES TO translated-text
STRING target-1 (1:t1)
target-2 (1:t2)
target-2 (1:t2)
target-2 (1:t2)
...
DELIMITED BY SIZE INTO translated-text
END-STRING
选项 b) 带有两个指针的简单 PERFORM VARYING
,结合简单的 IF
语句。
*> you may get more performance if you `REDEFINE` source-text as a `PIC X OCCURS length-of-text TIMES` - but I find this one more better to read and it shouldn't consume much more time...
MOVE 0 TO target-pointer
PERFORM VARYING source-pointer
FROM 1 BY 1
UNTIL source-pointer > length-of-text
IF source-text (source-pointer:1) = '#'
*> a very good optimizer would calculate the constant on the
*> right side, you may write it directly
IF source-pointer + 4 > length-of-text
ADD 1 TO target-pointer
MOVE source-text (source-pointer:)
TO target-text (target-pointer:)
EXIT PERFORM
END-IF
IF source-text (source-pointer:4) = '#RT#' OR '#LT#' OR ...
ADD 4 TO source-pointer
EXIT PERFORM CYCLE
END-IF
END-IF
ADD 1 TO target-pointer
MOVE source-text (source-pointer:1)
TO target-text (target-pointer:1)
END-PERFORM