none
String in einer Datei suchen und zählen RRS feed

  • Frage

  • Hallo zusammen

    Es gibt zwei Dateien. In der ersten Datei (die nenne ich mal raw) gibt es viele Benutzernamen, in der zweiten Datei (die nenne ich mal unique) gibt es jeden Benutzernamen, der in der Datei raw ist, genau ein Mal.

    Auszug Datei raw:

    Benutzer 1

    Benutzer 2

    Benutzer 3

    Benutzer 2

    Benutzer 1

    Auszug Datei unique:

    Benutzer 1

    Benutzer 2

    Benutzer 3

    Jetzt möchte ich wissen, wie oft jeder Benutzer aus der Datei unique in der Datei raw vorhanden ist.

    Mit diesem Code funktionierts:

    Get-Content "unique" | ForEach-Object {
    	$c = $_
    	$d = Get-Content "raw" | where {$_ -match $c}; $e = $d.Count; IF (!$e) {$e = 1};
    	Write-Output ${c}";"${e} | Out-File "output.txt" -Append
    }
    
    Es dauert aber viel zu lange bis alle Files durchgefiltert sind, der Code kann bestimmt noch irgendwie optimiert werden. Hat jemand einen Tipp?

    Freitag, 25. November 2011 12:00

Antworten

  • Hallo, >Mit diesem Code funktionierts:


    Get-Content "unique" | ForEach-Object { $c = $_ $d = Get-Content "raw" | where {$_ -match $c}; $e = $d.Count; IF (!$e) {$e = 1}; Write-Output ${c}";"${e} | Out-File "output.txt" -Append }

    Es dauert aber viel zu lange bis alle Files durchgefiltert sind, der Code kann bestimmt noch irgendwie optimiert werden. Hat jemand einen Tipp?

    Also zuerst solltest Du mal Get-Content "raw" aus der Schleife nehmen, oder ändert sich der Inhalt zwischen den Durchläufen? Dann kannst Du die Suche mit "select-string" machen, ist vermutlich schneller. Die Zeile "IF (!$e) {$e = 1}" ist IMHO falsch, da $e dann leer ist, wenn es KEINEN oder EINEN Treffer gab. Und am Ende kann man noch einige Variablen rausnehmen:
    $raw = Get-Content "raw"
    Get-Content "unique.txt" | ForEach-Object {
            $e = @($raw | select-String -SimpleMatch $_).count
            Write-Output ${_}";"${e} | Out-File "output.txt" -Append
    }

    Grüße aus Berlin schickt Robert
    MVP Exchange Server
    • Als Antwort markiert Power22 Freitag, 25. November 2011 14:19
    Freitag, 25. November 2011 12:46

Alle Antworten

  • Hallo, >Mit diesem Code funktionierts:


    Get-Content "unique" | ForEach-Object { $c = $_ $d = Get-Content "raw" | where {$_ -match $c}; $e = $d.Count; IF (!$e) {$e = 1}; Write-Output ${c}";"${e} | Out-File "output.txt" -Append }

    Es dauert aber viel zu lange bis alle Files durchgefiltert sind, der Code kann bestimmt noch irgendwie optimiert werden. Hat jemand einen Tipp?

    Also zuerst solltest Du mal Get-Content "raw" aus der Schleife nehmen, oder ändert sich der Inhalt zwischen den Durchläufen? Dann kannst Du die Suche mit "select-string" machen, ist vermutlich schneller. Die Zeile "IF (!$e) {$e = 1}" ist IMHO falsch, da $e dann leer ist, wenn es KEINEN oder EINEN Treffer gab. Und am Ende kann man noch einige Variablen rausnehmen:
    $raw = Get-Content "raw"
    Get-Content "unique.txt" | ForEach-Object {
            $e = @($raw | select-String -SimpleMatch $_).count
            Write-Output ${_}";"${e} | Out-File "output.txt" -Append
    }

    Grüße aus Berlin schickt Robert
    MVP Exchange Server
    • Als Antwort markiert Power22 Freitag, 25. November 2011 14:19
    Freitag, 25. November 2011 12:46
  • "Also zuerst solltest Du mal Get-Content "raw" aus der Schleife nehmen, oder ändert sich der Inhalt zwischen den Durchläufen?"

    Nein, bleibt gleich, das hab ich aus der Schleife genommen.

    "Die Zeile "IF (!$e) {$e = 1}" ist IMHO falsch, da $e dann leer ist, wenn es KEINEN oder EINEN Treffer gab."

    Diese Zeile musste ich nehmen, damit eine 1 geschrieben wird, wenn der Benutzername nur 1x gefunden wird. Dass es keinen Treffer gibt ist nicht möglich, denn die Datei unique wird aus der Datei raw generiert. Gäbe es eine andere Möglichkeit, dass bei nur einem Treffer eine 1 anstatt gar nichts geschrieben wird?

    Hab noch ein paar Variablen entfernt.

    Naja, die Datei raw hat ca 6'000 Zeilen und die Datei unique ca. 1'000, da wird es wohl schon ne Weile dauern bis diese Dateien gefilter wurden ...

    Freitag, 25. November 2011 13:26
  • "Die Zeile "IF (!$e) {$e = 1}" ist IMHO falsch, da $e dann leer ist, wenn es KEINEN oder EINEN Treffer gab."

    Diese Zeile musste ich nehmen, damit eine 1 geschrieben wird, wenn der Benutzername nur 1x gefunden wird. Dass es keinen Treffer gibt ist nicht möglich, denn die Datei unique wird aus der Datei raw generiert. Gäbe es eine andere Möglichkeit, dass bei nur einem Treffer eine 1 anstatt gar nichts geschrieben wird?

    Schau mal in meinen Vorschlag, da ist das eleganter gelöst.

    Naja, die Datei raw hat ca 6'000 Zeilen und die Datei unique ca. 1'000, da wird es wohl schon ne Weile dauern bis diese Dateien gefilter wurden ...

    Und, wie schnell ist mein Vorschlag im Gegensatz zu Deinem? Ich habe das nur mit drei Zeilen getestet, nicht mit 6000.


    Grüße aus Berlin schickt Robert
    MVP Exchange Server
    Freitag, 25. November 2011 13:28
  • Ah ich habs gefunden, mit dem @ ist es eleganter. Ich habe nicht genau auf die Zeit gesehen, dass Script ist jetzt jedoch schneller. Danke für deine schnelle Hilfe. Das ging ja fix.
    Freitag, 25. November 2011 14:19
  • Ah ich habs gefunden, mit dem @ ist es eleganter.

    Ja, der Konstrukt @() (mit den Klammern vorne und hinten!) führt dazu, dass immer ein Array angelegt wird, auch wenn es keine oder nur eine Zeile gibt.

    Ich habe nicht genau auf die Zeit gesehen, dass Script ist jetzt jedoch schneller. Danke für deine schnelle Hilfe. Das ging ja fix.

    Ich hatte gerade in einem Kurs ein sehr ähnliches Problem besprochen. Aber freut mich, dass ich helfen konnte!


    Grüße aus Berlin schickt Robert
    MVP Exchange Server
    Freitag, 25. November 2011 14:33