我有一个csv文件,其中包含主机名和附加的序列号。我想创建一个键值对,键为主机名,值为序列号列表。序列号可以是一个或多个。
例如:
A, 1, 2, 3, 4
B, 5, 6
C, 7, 8, 9
D, 10
我需要访问密钥A
并获取{1 2 3 4}
作为输出。如果我访问D,我应该{10}
我该怎么做?由于我使用的TCL版本不支持CSV等任何软件包,因此我也无法安装它,因为它在服务器中,所以我正在寻找一种不会解决问题的解决方案。包括任何包裹。
目前,我正在使用\n
拆分该行,然后处理每个元素。然后我用","分割元素。然后我在列表中获取主机名和序列号。然后,我将列表的第0个索引用作主机名,将剩余值用作序列号。有更清洁的解决方案吗?
答案 0 :(得分:0)
我会做类似的事情:
#!/usr/bin/env tclsh
package require csv
package require struct::queue
set filename "file.csv"
set fh [open $filename r]
set q [struct::queue]
csv::read2queue $fh $q
close $fh
set data [dict create]
while {[$q size] > 0} {
set values [lassign [$q get] hostname]
dict set data $hostname [lmap elem $values {string trimleft $elem}]
}
dict for {key value} $data {
puts "$key => $value"
}
然后
$ tclsh csv.tcl
A => 1 2 3 4
B => 5 6
C => 7 8 9
D => 10
答案 1 :(得分:0)
这里给出的重复建议是使用CSV包来实现此目的。另请参阅@ glenn-jackman的答案。如果不可用,则在服务器端获取它的时间会更好。
然而,为了让您开始,您可能希望采用以下方式:
set dat {
A, 1, 2, 3, 4
B, 5, 6
C, 7, 8, 9
D, 10
}
set d [dict create]
foreach row [split [string trim $dat] \n] {
set row [lassign [split $row ,] key]
dict set d [string trim $key] [concat {*}$row]
}
dict get $d A
dict get $d D
但是,请注意,当您完全控制正在处理的数据及其表示时,这种手工编织的解决方案通常仅用于其目的。同样,通过获取CSV包可以更好地投入时间。
答案 2 :(得分:0)
我试过这种方式让它运转起来。再次感谢您的投入。是的,我知道csv包很简单,但我不能在服务器/产品中安装它。
set multihost "host_slno.csv"
set fh1 [open $multihost r]
set data [read -nonewline $fh1]
close $fh1
set hostslnodata [ split $data "\n" ]
set hostslno [dict create];
foreach line $hostslnodata {
set line1 [join [split $line ", "] ]
puts "$line1"
if {[regexp {([A-Za-z0-9_\-]+)\s+(.*)} $line1 match hostname serial_numbers]} {
dict lappend hostslno $hostname $serial_numbers
}
}
puts [dict get $hostslno]
答案 3 :(得分:0)
csv包中的源代码可用。如果您无法安装完整的csv软件包,则可以在此处添加代码:
http://core.tcl.tk/tcllib/artifact/2898cd911697ecdb
如果您仍然不能使用该选项,则需要去除所有空白并在“,”上分割。
较早的答案的替代方法是使用字符串映射:
set row [split [string map {" " ""} $row ] ,]
字符串映射将删除所有空格,然后在“,”上分割
将文本行转换为有效的tcl列表后:
A 1 2 3 4
B 5 6
C 7 8 9
D 10
然后,您可以使用lindex和lrange命令完成所有操作。
foreach row $data {
set server [lindex $row 0]
set serial_numbers [lrange $row 1 end]
dict set ...
答案 4 :(得分:0)
一种可能性:
set hostslno [dict create]
set multihost "host_slno.csv"
set fh1 [open $multihost]
while {[gets $fh line] >= 0} {
set numbers [lassign [regexp -inline -all {[^\s,]+} $line] hostname]
dict set hostslno $hostname $numbers
}
close $fh1
puts [dict get $hostslno A]