1

「file1」の文字列 (40 ~ 400 文字以上) が「file2」で効果的な方法で発生する回数を取得しようとしています。file1 には約 2k 行、file2 には約 130k 行があります。私は現在、VMで約2分、Cygwinで約5分で実行できるUnixソリューションを持っていますが、ファイルが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"    
}
4

2 に答える 2

0

スクリプトの問題の 1 つはfile2.csvfile1.csv. ファイルを一度だけ読み取り、その内容を変数に格納すると、処理が大幅に高速化されます。これを試して:

$f2 = Get-Content .\file2.csv

foreach ($line in (gc .\file1.csv)) {
  $line = $line.Substring(0,180)
  @($f2 | ? { $_ -match $line }).Count
}
于 2013-06-26T15:32:08.393 に答える