2016-11-05 30 views
2

私はテキストファイルの単語を数えようとしていますが、取得すると配列は文字で1文字ずつ読み込まれるため、単語ごとに単語を比較することはできません。私はあなたが私を助けることができることを願っています!Powershell単語単位でテキストファイルを読む

$poem = $line     # set poem to $null (because $line is undefined) 
$Articles = "a","an","the"  # $Articles is an array of strings, ok 

           # check file exists (I skipped, it's fine) 

$poem = Get-Content "text.txt" # Load content into $poem, 
           # also an array of strings, ok 

$poem.Split(" ")     # Apply .Split(" ") to the array. 
           # Powershell does that once for each line. 
           # You don't save it with $xyz = 
           # so it outputs the words onto the 
           # pipeline. 
           # You see them, but they are thrown away. 

Get-Articles      # Call a function (with no parameters) 


function Get-Articles(){   

           # Poem wasn't passed in as a parameter, so 
foreach($Word in $poem){  # Pull poem out of the parent scope. 
           # Still the original array of lines. unchanged. 
           # $word will then be _a whole line_. 

    if($Articles -contains $Word){ # $articles will never contain a whole line 
     $Counter++ 
    } 
} 
    write-host "The number of Articles in your sentence: $counter" # 0 everytime 
} 

あなたはおそらくそれ言葉の代わりに、行の配列にする$poem = $poem.Split(" ")をやってみたかった:あなたのスクリプトは、少し下に編集したん何

クリアホスト #Functions

function Get-Articles(){ 

foreach($Word in $poem){ 
    if($Articles -contains $Word){ 
     $Counter++ 
    } 
} 
    write-host "The number of Articles in your sentence: $counter" 
} 

#Variables 

$Counter = 0 

$poem = $line 
$Articles = "a","an","the" 

#Logic 

$fileExists = Test-Path "text.txt" 

if($fileExists) { 
    $poem = Get-Content "text.txt" 
    } 
else 
    { 
    Write-Output "The file SamMcGee does not exist" 
    exit(0) 
    } 

$poem.Split(" ") 

Get-Articles 

答えて

3

それとも、

function Get-Articles ($poem) { 
... 

Get-Articles $poem.Split(" ") 

で関数に$の詩の言葉に合格している可能性があり、あなたがPowerShellのパイプラインを利用することができます

$Articles = "a","an","the" 

$poemArticles = (Get-Content "text.txt").Split(" ") | Where {$_ -in $Articles} 
$counter = $poemArticles | Measure | Select -Expand Count 
write-host "The number of Articles in your sentence: $counter" 
+0

各単語でScriptblockが実行され、PowerShellではscriptblock呼び出しのオーバーヘッドが大きく、PSのパイプライン処理が遅くなるため、これはこれまでのところ最も遅い解決策です。最も速いものがコメントに記述されています: '(Select-String '\ b(a | an | the)\ b' text.txt -AllMatches).Matches.Count'。問題の元のコードは、各行またはテキスト内容の文字列全体で 'split'を使うことで修正されていれば、ほぼ速いです。 – wOxxOm

1

TessellatingHeckler's helpful answerはよくあなたのアプローチの問題点を説明します。

はここにあなたのコマンドの根本簡易版です:

$counter = (-split (Get-Content -Raw text.txt) -match '^(a|an|the)$').count 
write-host "The number of articles in your sentence: $counter" 

-splitオペレータの単項フォームはここで重要である:それは結果として、により単語間の空白のいずれかの実行を言葉に入力を分割個々の単語の配列で。 ^(a|an|the)$

-matchは、次に単語aan、又はtheに一致する正規表現に対する単語の結果の配列と一致します。

結果は、目的の単語だけを含む入力配列のフィルタリングされたサブアレイであり、.countは、そのサブアレイのカウントを単純に返します。

+1

'Select-String'は-splitよりも短く、get-contentとmatchを組み合わせたと思うでしょうか? '(Select-String '\ b(a | an | the)\ b' text.txt -AllMatches).Matches.Count'を指定しないでください。 \ b(* | '| measure -word).Words'も短くはありません。 :/ – TessellatingHeckler

+0

@TessellatingHeckler:あなたのバリエーションをパフォーマンスの面で比較すると面白いでしょう。 – mklement0

+1

Impromptuのテストでは、先ほどPoShヘルプをローカルで1.4MBのテキストで保存しています。ファイルセレクタを '* .txt'に変更すると、あなたのアプローチは0.5秒かかり、記事数は20,409、私の' select-string'は0.35秒、記事数は20,953件、my -replaceは5.8秒、83,712です。おそらく最後のものを割り引くでしょう。しかし、私の単語境界正規表現は、あなたのスペース分割が逃してしまう '' the ''のようなものを見つけている可能性があります。 – TessellatingHeckler

関連する問題