2016-11-05 11 views
2

Ich versuche also, die Wörter meiner Textdatei zu zählen, aber wenn ich Get-Content erhalte, liest das Array sie Buchstaben für Buchstaben und lässt mich nicht Wort für Wort vergleichen . Ich hoffe ihr könnt mir helfen!Powershell Textdatei Wort für Wort lesen

Clear-Host #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 

Antwort

3

Was Ihr Skript hat, ein wenig bearbeitet bis:

$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 
} 

Sie wollten wahrscheinlich $poem = $poem.Split(" ") tun es eine Reihe von Wörtern anstelle von Linien zu machen .

Oder Sie $ Gedicht Worte in die Funktion haben könnte bestanden mit

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

Get-Articles $poem.Split(" ") 

Und Sie könnten die Verwendung der Powershell-Pipeline mit machen: gut

$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 in 'Where' wird für jedes Wort ausgeführt, und da der Aufwand für Skriptblockaufrufe in PowerShell sehr groß ist, verbunden mit der Langsamkeit des Pipelining in PS, ist dies bei weitem die langsamste Lösung. Der schnellste wird in einem Kommentar erwähnt: '(Select-String '\ b (a | an | der) \ b' text.txt -AllMatches) .Matches.Count'. Der ursprüngliche Code in der Frage ist fast so schnell, vorausgesetzt, es wird mit 'split' in jeder Zeile oder in der gesamten Textinhalts-Zeichenfolge behoben. – wOxxOm

1

TessellatingHeckler's helpful answer erklärt das Problem mit Ihrem Ansatz.

Hier ist eine radikal vereinfachte Version des Befehls:

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

Die einstellige Form des -split Betreiber ist der Schlüssel hier: sie die Eingabe in Worte durch spaltet Befehl Run von Leerzeichen zwischen den Wörtern, was in einer Reihe von einzelnen Wörtern.

-match dann entspricht das resultierende Array von Wörtern, die vor einem regulären Ausdruck übereinstimmt Worten a, an oder the: ^(a|an|the)$.

Das Ergebnis ist das gefilterte Subarray des Eingabearrays, das nur die gewünschten Wörter enthält, und .count gibt einfach die Anzahl der Unterarrays zurück.

+1

Sie würden denken, Select-String wäre kürzer als -Split und Get-Content und Match kombiniert, wie? aber keine '(Select-String '\ b (a | an | die) \ b' text.txt -AllMatches) .Matches.Count'. Und '(Get-Content -Raw text.txt) -replace '. *? \ B (a | an | das) \ b. *?' | Measure -word) .Worte' ist auch nicht kürzer. : -/ – TessellatingHeckler

+0

@TessellatingHeckler: Es wäre interessant zu sehen, wie sich Ihre Varianten jedoch in Bezug auf die Leistung vergleichen. – mklement0

+1

Impromptu Test, ich habe gerade zufällig die PoSh Hilfe lokal früher gespeichert, 1,4 MB Text. Wenn du den Dateiwähler auf '* .txt' änderst, dauert dein Ansatz 0.5s und findet 20.409 Artikel, mein' select-string' dauert 0.35s und findet 20.953 Artikel, und mein -replace braucht 5.8s und findet 83.712. Wahrscheinlich Rabatt, dass letzte. Aber mein Wort Grenze Regex ist möglicherweise finden Dinge wie "" die Ihre Raumaufteilung würde vermissen. – TessellatingHeckler

Verwandte Themen