从文本文件中读取特定的数据列并写入另一个文本文件t

时间:2015-11-02 06:09:42

标签: tcl

使用Tcl。例如,我有数据

您好;世界; 123

测试;代码; 456

我只想获取第一列的值并将其写入另一个文本文件。输出将是这样的。

您好

测试

2 个答案:

答案 0 :(得分:2)

您只需从输入文件中读取:

set pfi [open "file_name" "r"]
set cnt [gets $pfi row]

然后过滤第一个单词:

set word [lindex [split $row ";"] 0]

然后写入输出文件

set pfo [open "file_out_name" "w"]
puts $pfo $word

您可以使用cnt知道文件的结尾是否到来(当cnt <0文件结束时),这样您就可以迭代所有文件行。当然,最后,关闭文件是必要的:

close $pfi
close $pfo

所以,结合所有步骤:

set pfi [open "file_in_name" "r"]
set pfo [open "file_out_name" "w"]
while {1 == 1} {
    set cnt [gets $pfi row]
    if {$cnt < 0} {break}
    set word [lindex [split $row ";"] 0]
    puts $pfo $word
}
close $pfi
close $pfo

答案 1 :(得分:0)

啊好吧......

有几种方法可以做到这一点。如果你在类似unix的平台上,cut命令是正确的方式,来自Tcl或shell脚本。当然,Tcl也可以做到这一点,虽然不那么方便(脚本很难与实用程序竞争)。

最简单的解决方案利用fileutil,这是世界上被低估的软件包之一:

package require fileutil
namespace import ::fileutil::*

一个命令foreachLine允许我们为文件中的每一行(data.old)执行某些操作:

foreachLine line data.old {appendToFile data.new [lindex [split $line \;] 0]\n}

我们在这里做的是将每行所需的单词追加到另一个文件(data.new)。

我们还可以在一个命令的帮助下就地编辑文件,该命令将文件的内容分成行,将每一行截断为第一个子字符串直到分号,然后重新加入这些行:

proc cmd data {
    join [lmap line [split [string trim $data] \n] {
        lindex [split $line \;] 0
    }] \n
}

然后我们这样做(注意这取代了原始内容):

updateInPlace data.old cmd

对于不严格按行进行的操作,这是一个更复杂但更实用的操作。

另外两个软件包对字符分隔数据很有用:csv用于导入数据集,struct::matrix用于操作数据。

package require csv
package require struct::matrix

::struct::matrix m

将数据导入矩阵m(由于包的定义方式,我们需要在此处理通道):

set old [open data.old]
::csv::read2matrix $old m \; auto
chan close $old

从矩阵中获取第一列:

set data [m get column 0]

将截断的数据写入文件:

writeFile data.new [join $data \n]

当然也可以以低级核心Tcl方式执行此操作。这个解决方案与Andrea Tosoni相似,但更具惯用性。

set old [open data.old]
set new [open data.new w]
while {[chan gets $old line] >= 0} {
    chan puts $new [lindex [split $line \;] 0]
}
chan close $old
chan close $new

文档:chancsv包,fileutil包,joinlappendlindexlmap,{ {3}}替换,lmapnamespaceopenpackagesetsplit包,struct::matrix