如何使用tcl屏蔽文件中包含的敏感信息?
我正在尝试实现一个tcl脚本,它读取一个文本文件,屏蔽其中包含的所有敏感信息(如密码、ip地址等),并将输出写入另一个文件 现在我只是用**或#######替换这些数据,然后用regexp搜索整个文件以找到需要屏蔽的内容。但由于我的文本文件可以是10万行或更多的文本,这是非常低效的 是否有任何内置的tcl函数/命令可以让我更快地实现这一点?是否有任何附加程序包提供了额外的选项来帮助完成此任务如何使用tcl屏蔽文件中包含的敏感信息?,tcl,password-encryption,Tcl,Password Encryption,我正在尝试实现一个tcl脚本,它读取一个文本文件,屏蔽其中包含的所有敏感信息(如密码、ip地址等),并将输出写入另一个文件 现在我只是用**或#######替换这些数据,然后用regexp搜索整个文件以找到需要屏蔽的内容。但由于我的文本文件可以是10万行或更多的文本,这是非常低效的 是否有任何内置的tcl函数/命令可以让我更快地实现这一点?是否有任何附加程序包提供了额外的选项来帮助完成此任务 注意:我使用的是tcl 8.4(但如果在较新版本的tcl中有这样做的方法,请告诉我)一个有100K行的文
注意:我使用的是tcl 8.4(但如果在较新版本的tcl中有这样做的方法,请告诉我)一个有100K行的文件没有那么多(除非每行都是1K字符长:),所以我建议您
将整个文件读入一个var,并对该var进行替换:
set fd [open file r+]
set buf [read $fd]
set buf [regsub -all $(the-passwd-pattern) $buf ****]
# write it back
seek $fd 0; # This is not safe! See potrzebie's comment for details.
puts -nonewline $fd $buf
close $fd
一个有100K行的文件没有那么多(除非每行都有1K个字符长:),所以我建议您将整个文件读入一个var,并对该var进行替换:
set fd [open file r+]
set buf [read $fd]
set buf [regsub -all $(the-passwd-pattern) $buf ****]
# write it back
seek $fd 0; # This is not safe! See potrzebie's comment for details.
puts -nonewline $fd $buf
close $fd
特别是对于非常大的文件(如前所述),将整个文件读入变量并不是最好的方法。一旦系统内存耗尽,您就无法防止应用程序崩溃。对于由换行符分隔的数据,最简单的解决方案是缓冲一行并对其进行处理
举个例子:
# Open old and new file
set old [open "input.txt" r]
set new [open "output.txt" w]
# Configure input channel to provide data separated by line breaks
fconfigure $old -buffering line
# Until the end of the file is reached:
while {[gets $old ln] != -1} {
# Mask sensitive information on variable ln
...
# Write back line to new file
puts $new $ln
}
# Close channels
close $old
close $new
我想不出任何更好的方法来处理Tcl中的大文件-请随时告诉我任何更好的解决方案。但Tcl并不是用来处理大型数据文件的。为了获得真正的性能,您可以使用编译语言而不是脚本编程语言
编辑:已替换![eof$old]
在while循环中。特别是对于非常大的文件-如前所述-这不是将整个文件读入变量的最佳方式。一旦系统内存耗尽,您就无法防止应用程序崩溃。对于由换行符分隔的数据,最简单的解决方案是缓冲一行并对其进行处理
举个例子:
# Open old and new file
set old [open "input.txt" r]
set new [open "output.txt" w]
# Configure input channel to provide data separated by line breaks
fconfigure $old -buffering line
# Until the end of the file is reached:
while {[gets $old ln] != -1} {
# Mask sensitive information on variable ln
...
# Write back line to new file
puts $new $ln
}
# Close channels
close $old
close $new
我想不出任何更好的方法来处理Tcl中的大文件-请随时告诉我任何更好的解决方案。但Tcl并不是用来处理大型数据文件的。为了获得真正的性能,您可以使用编译语言而不是脚本编程语言
编辑:已替换![eof$old]
在while循环中。一般来说,您应该将代码放入一个过程中,以获得Tcl的最佳性能。(在8.5和8.6中还有一些相关选项,例如lambda术语和类方法,但它们与过程密切相关。)您还应该注意一些其他事项:
- 将表达式放在大括号中(
expr{$a+$b}
而不是expr$a+$b
),这样可以实现更高效的编译策略
- 仔细选择频道编码。(如果您配置$chan-TRANSION binary
,该通道将传输字节而不是字符。但是,GET
在8.4中对面向字节的通道不是非常有效。使用编码iso8859-1-TRANSION lf
将提供大部分好处。)
Tcl在通道缓冲方面做得很好
也许值得用不同版本的Tcl对您的代码进行基准测试,看看哪一个版本效果最好。如果您不想为了测试而安装多个Tcl解释器,那么可以尝试使用一个用于测试的解释器
执行面向行的转换的惯用方法是:
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Iterate over the lines, applying the replacement
while {[gets $fin line] >= 0} {
regsub -- $RE $line $replacement line
puts $fout $line
}
# All done
close $fin
close $fout
}
如果文件足够小,可以很容易地放入内存中,这会更有效,因为整个match replace循环将提升到C级别:
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Apply the replacement over all lines
regsub -all -line -- $RE [read $fin] $replacement outputlines
puts $fout $outputlines
# All done
close $fin
close $fout
}
最后,正则表达式不一定是进行字符串匹配的最快方法(例如,stringmatch
要快得多,但接受的模式类型要限制得多)。将一种类型的替换代码转换为另一种类型并使其快速运行并非易事(REs非常灵活)。一般来说,您应该将代码放入一个过程中,以获得Tcl的最佳性能。(在8.5和8.6中还有一些相关选项,例如lambda术语和类方法,但它们与过程密切相关。)您还应该注意一些其他事项:
- 将表达式放在大括号中(
expr{$a+$b}
而不是expr$a+$b
),这样可以实现更高效的编译策略
- 仔细选择频道编码。(如果您配置$chan-TRANSION binary
,该通道将传输字节而不是字符。但是,GET
在8.4中对面向字节的通道不是非常有效。使用编码iso8859-1-TRANSION lf
将提供大部分好处。)
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Iterate over the lines, applying the replacement
while {[gets $fin line] >= 0} {
regsub -- $RE $line $replacement line
puts $fout $line
}
# All done
close $fin
close $fout
}
如果文件足够小,可以很容易地放入内存中,这会更有效,因为整个match replace循环将提升到C级别:
proc transformFile {sourceFile targetFile RE replacement} {
# Open for reading
set fin [open $sourceFile]
fconfigure $fin -encoding iso8859-1 -translation lf
# Open for writing
set fout [open $targetFile w]
fconfigure $fout -encoding iso8859-1 -translation lf
# Apply the replacement over all lines
regsub -all -line -- $RE [read $fin] $replacement outputlines
puts $fout $outputlines
# All done
close $fin
close $fout
}
最后,正则表达式不一定是进行字符串匹配的最快方法(例如,
stringmatch
要快得多,但接受的模式类型要限制得多)。将一种类型的替换代码转换为另一种类型并使其快速运行并非易事(REs非常灵活)。未经测试,但我相信一些脚本语言(如Perl
)应该能够执行非常出色的性能