如何使用tcl屏蔽文件中包含的敏感信息?

如何使用tcl屏蔽文件中包含的敏感信息?,tcl,password-encryption,Tcl,Password Encryption,我正在尝试实现一个tcl脚本,它读取一个文本文件,屏蔽其中包含的所有敏感信息(如密码、ip地址等),并将输出写入另一个文件 现在我只是用**或#######替换这些数据,然后用regexp搜索整个文件以找到需要屏蔽的内容。但由于我的文本文件可以是10万行或更多的文本,这是非常低效的 是否有任何内置的tcl函数/命令可以让我更快地实现这一点?是否有任何附加程序包提供了额外的选项来帮助完成此任务 注意:我使用的是tcl 8.4(但如果在较新版本的tcl中有这样做的方法,请告诉我)一个有100K行的文

我正在尝试实现一个tcl脚本,它读取一个文本文件,屏蔽其中包含的所有敏感信息(如密码、ip地址等),并将输出写入另一个文件

现在我只是用**或#######替换这些数据,然后用regexp搜索整个文件以找到需要屏蔽的内容。但由于我的文本文件可以是10万行或更多的文本,这是非常低效的

是否有任何内置的tcl函数/命令可以让我更快地实现这一点?是否有任何附加程序包提供了额外的选项来帮助完成此任务


注意:我使用的是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
    将提供大部分好处。)
  • 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非常灵活)。

    未经测试,但我相信一些脚本语言(如
    Perl
    )应该能够执行非常出色的性能