我正在编写一个结合了两个文本文件部分的脚本。这些文件不是太大(每个约2000行)。 我看到select-string的奇怪输出,我认为不应该存在。 这是我的两个文件的样本:
CC.csv - 2026行
LS126L47L6/1L2#519,07448,1,B
LS126L47L6/1R1-1#503,07449,1,B
LS126L47L6/1L3#536,07450,1,B
LS126L47L6/2R1#515,07451,1,B
LS126L47L6/10#525,07452,1,B
LS126L47L6/1L4#538,07453,1,B
GI.txt - 1995行
07445,B,SH,1
07446,B,SH,1
07448,B,SH,1
07449,B,SH,1
07450,B,SH,1
07451,B,SH,1
07452,B,SH,1
07453,B,SH,1
07454,B,SH,1
这是输出文件的示例:
输出myfile.csv
LS126L47L6/3R1#516,07446,1,B
LS126L47L6/1L2#519,07448,1,B
LS126L47L6/1R1-1#503,07449,1,B
System.Object[],B
LS126L47L6/2R1#515,07451,1,B
这是我正在使用的脚本:
sc ./myfile.csv "col1,col2,col3,col4"
$mn = gc cc.csv | select -skip 1 | % {$_.tostring().split(",")[1]}
$mn | % {
$a = (gc cc.csv | sls $_ ).tostring() -replace ",[a-z]$", ""
if (gc GI.txt | sls $_ | select -first 1)
{$b = (gc GI.txt | sls $_ | select -first 1).tostring().split(",")[1]}
else {$b = "NULL"
write-host "$_ is not present in GI file"}
$c = $a + ',' + $b
ac ./myfile.csv -value $c
}
$ a变量是我有时将返回的字符串看作 System.Object [] 的地方 有什么想法吗?此外,此脚本需要相当长的时间才能完成。关于如何加速它的任何提示?
编辑:我应该补充一点,我从cc.csv文件中取一行,保存在一个新的文本文件中,然后通过分配$ a在控制台中运行脚本。我无法让它返回" system.object []"。
编辑2:按照下面的建议并尝试了几件我已经注意到的事情,如果我跑了
$mn | %{(gc cc.csv | sls $_).tostring()}
我得到System.Object []。
但如果我跑
$mn | %{(gc cc.csv | sls $_)} | %{$_.tostring()}
很好。去图。
答案 0 :(得分:0)
问题是由匹配多重性的变化引起的。如果有多个匹配元素,则返回Object[]
数组(MatchInfo元素);单个匹配元素会生成一个MatchInfo
对象(数组中不);如果没有匹配项,则返回null
。
当针对" cc.csv"执行时,请考虑这些结果。提供的测试数据:
# matches many
(gc cc.csv | Select-String "LS" ).GetType().Name # => Object[]
# matches one
(gc cc.csv | Select-String "538").GetType().Name # => MatchInfo
# matches none
(gc cc.csv | Select-String "FAIL") # => null
在Object []上调用ToString
的结果是" System.Object []"而当直接在MatchInfo对象上调用时,结果是匹配值的更有用的串联。
可以使用selected | Select -First 1
修复直接问题,这将导致前两种情况返回MatchInfo。 Select-String仍会搜索整个输入 - 只会丢弃额外的结果。
然而,它似乎回顾了" cc.csv" (使用Select-String)可以完全消除,因为$_
最初来自哪里。这是一个小的[未经测试的]改编,它可能是什么样的:
gc cc.csv | Select -Skip 1 | %{
$num = $_.Split(",")[1]
$a = $_ -Replace ",[a-z]$", ""
# This is still O(m*n) and could be improved with a hash/set probe.
$gc_match = Select-String $num -Path gi.csv -SimpleMatch | Select -First 1
if ($gc_match) {
# Use of "Select -First 1" avoids the initial problem; but
# it /may/ be more appropriate for an error to indicate data problems.
# (Likewise, an error in the original may need further investigation.)
$b = $gc_match.ToString().Split(",")[1]
} else {
$b = "NULL"
Write-Host "$_ is not present in GI file"
}
$c = $a + ',' + $b
ac ./myfile.csv -Value $c
}