![](/img/trans.png)
[英]Create a hashmap that contains strings and a list in powershell?
[英]Powershell: Count instances of strings in a file using a list
我试图以有效的方式获取“ file1”中的字符串(从40到400个以上的字符)在“ file2”中出现的次数。 file1大约有2k行,file2大约有13万行。 我目前有一个Unix解决方案,它在VM中大约需要2分钟,在Cygwin中大约需要5分钟,但是由于文件在Windows中,并且我在excel中使用输出并使用它,因此我尝试使用Powershell / Python来完成此操作。自动化(AutoIT。)
我有一个解决方案,但是它花费的时间太长了(大约在Cygwin完成的同时-所有2k行-在Powershell中我只有40-50行!)尽管我还没有准备解决方案,但是我很开放如果有可以快速且准确的解决方案,也可以使用Python。
这是Unix代码:
while read SEARCH_STRING;
do printf "%s$" "${SEARCH_STRING}";
grep -Fc "${SEARCH_STRING}" file2.csv;
done < file1.csv | tee -a output.txt;
这是我目前拥有的Powershell代码
$Target = Get-Content .\file1.csv
Foreach ($line in $Target){
#Just to keep strings small, since I found that not all
#strings were being compared correctly if they where 250+ chars
$line = $line.Substring(0,180)
$Coll = Get-Content .\file2.csv | Select-string -pattern "$line"
$cnt = $Coll | measure
$cnt.count
}
任何建议的想法都会有所帮助。
谢谢。
编辑
我正在尝试CB建议的修改后的解决方案
del .\output.txt
$Target = Get-Content .\file1.csv
$file= [System.IO.File]::ReadAllText( "C:\temp\file2.csv" )
Foreach ($line in $Target){
$line = [string]$line.Substring(0, $line.length/2)
$cnt = [regex]::matches( [string]$file, $line).count >> ".\output.txt"
}
但是,由于file1中的字符串长度有所变化,因此我不断收到SubString函数的OutOfBound异常,因此我将输入字符串减半(/ 2)以尝试匹配。 当我尝试将它们减半时,如果它有一个开放的括号,它将告诉我:
Exception calling "Matches" with "2" argument(s): "parsing "CVE-2013-0796,04/02/2013,MFSA2013-35 SeaMonkey: WebGL
crash with Mesa graphics driver on Linux (C" - Not enough )'s."
At C:\temp\script_test.ps1:6 char:5
+ $cnt = [regex]::matches( [string]$file, $line).count >> ".\output.txt ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentException
我不知道是否有办法提高powershell中的输入限制(目前我的最大大小是406,但将来可能会更大)或只是放弃并尝试使用Python解决方案。
有什么想法吗?
编辑
感谢@CB,我得到了正确的答案,它与Bash脚本的输出完全匹配。 这是将结果输出到文本文件的完整代码:
$Target = Get-Content .\file1.csv
$file= [System.IO.File]::ReadAllText( "C:\temp\file2.csv" )
Foreach ($line in $Target){
$cnt = [regex]::matches( $file, [regex]::escape($line)).count >> ".\output.txt"
}
试试看:
$Target = Get-Content .\file1.csv
$file= [System.IO.File]::ReadAllText( "c:\test\file2.csv" )
Foreach ($line in $Target){
$line = $line.Substring(0,180)
$cnt = [regex]::matches( $file, [regex]::escape($line)).count
}
脚本的一个问题是,对于file1.csv
每一行,您file2.csv
反复读取file1.csv
。 一次读取文件并将内容存储在变量中应该可以大大加快速度。 尝试这个:
$f2 = Get-Content .\file2.csv
foreach ($line in (gc .\file1.csv)) {
$line = $line.Substring(0,180)
@($f2 | ? { $_ -match $line }).Count
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.