从文本文件中读取特定列的数据并写入另一个文本文件 tcl
Reading specific column of data from text file and write to another text file tcl
通过使用 Tcl。例如,我有数据
hello;world;123
test;code;456
我只想获取第一列的值并将其写入另一个文本文件。输出将是这样的。
hello
test
您只需从输入文件中读取:
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
嗯嗯...
有几种方法可以做到这一点。如果您在类 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
文档:chan, csv package, fileutil package, join, lappend, lindex, lmap, lmap replacement, namespace, open, package, set, split, struct::matrix package, while
通过使用 Tcl。例如,我有数据
hello;world;123
test;code;456
我只想获取第一列的值并将其写入另一个文本文件。输出将是这样的。
hello
test
您只需从输入文件中读取:
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
嗯嗯...
有几种方法可以做到这一点。如果您在类 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
文档:chan, csv package, fileutil package, join, lappend, lindex, lmap, lmap replacement, namespace, open, package, set, split, struct::matrix package, while