none
Auswerten vom Ergebnis Get-Content -en byte -ReadCount 5 -TotalCount 5 RRS feed

  • Frage

  • Hallo,

    ich habe mir eine Abfrage zusammengebaut mit der ich prüfen möchte ob die ersten 5 Zeichen in einer Datei den Wert null haben.
    Hier meine ganze Abfrage:

    powershell.exe for ($i=2000; $i -le 2020; $i++) {Get-ChildItem -Path C:\Verteichnis\$i* -include *-*  -rec -force | Get-Content -en byte -ReadCount 5 -TotalCount 5 | where {$_ -eq 0 } | Get-ChildItem | select fullname | out-file -filepath Mail.txt -append}

    Es geht aber eigentlich nur um den Teil
    "Get-Content -en byte -ReadCount 5 -TotalCount 5 | where {$_ -eq 0 } | Get-ChildItem | select fullname"
    Wenn das erste und dritte Zeichen eine nul sind bekomme ich den Dateinamen zweimal zurückgegeben.
    Wenn die ersten fünf stellen null sind bekomme ich fünf mal den Dateinamen zurückgegeben.

    Ich möchte aber das ich den Dateinamen nur zurückbekommen, wenn die ersten 5 Zeichen Pro Datei alle nul sind.
    Wie muss ich den Befehl umstellen?

    Montag, 7. April 2014 15:05

Antworten

  • Du musst natürlich die summe der ersten 5 Bytes berechnen. Wenn die Summe = 0 ist sind alle 5 Bytes 0!

    Berechnungen kann man innerhalb der Pipeline nur machen wenn man den Scriptblock vom ForEach-Object Cmdlet dazu benutzt.

    In dem Scriptblock von dem ForEach-Object Cmdlet ist dann ein Script.
    Da die Befehle hier alle in einer Zeile stehen, muss man diese Befehle mit dem Semikolon Trennen damit PowerShell die Befehle als "einzelne Zeilen" abarbeitet.
    Mit dem Semikolon trennt man also einzelne Befehle, wenn Sie in einer Zeile stehen sollen.

    Da du das anscheinend als PowerShell.exe Einzeiler haben möchtest hier die "Einzeiler" Lösung (Ungetestet):

    powershell.exe -Command "& { & {for ($i=2000; $i -le 2020; $i++) {Get-ChildItem -Path C:\Verteichnis\$i* -include *-*  -rec -force  | ForEach-Object { $Path = $_.Fullname; ; $Sum = Invoke-Expression ((Get-Content -Path $Path -Encoding byte -ReadCount 5 -TotalCount 5) -join '+'); If($Sum -eq 0){ $Path} }}}  | Out-File Mail.txt -append}"



    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    • Als Antwort markiert Alex Pitulice Mittwoch, 23. April 2014 14:56
    Dienstag, 8. April 2014 06:15
  • Hätte ich gewusst das du das an 4mil Dateien machen musst hätte ich dir einen anderen Code gegeben.

    Get-Content ist sehr langsam....

    Invoke-Expression macht das noch langsamer (hier muss immer ein Text in Code umgesetzt werden)....

    Hier ein Code der das ganze VIEL, VIEL schneller tun sollte:

    # Ein Array erstellen mit allen Datei-Pfaden
    $Files = Get-ChildItem d:\temp -Filter *.txt | Select-Object -ExpandProperty Fullname
    
    # Jede Datei einzeln besuchen
    ForEach($File in $Files) {
        
        # FileStream erstellen
        $FileStream = [System.IO.File]::OpenRead($File)
        # Buffer für das Ergebnis bereitstellen
        $Bytes = [Byte[]]@(1,2,3,4,5)
        # 5 Bytes vom Anfang der Datei in den Buffer einlesen
        $FileStream.Read($Bytes,0,5)
        # Datei sofort wieder schliessen (wichtg!)
        $FileStream.Close()
    
        # Summe der Bytes bilden
        $Sum = 0
        # jedes Byte auf die Summe aufaddieren
        ForEach($Byte in $Bytes) {
            $Sum += $Byte
        }
    
        # wenn die summe der Bytes 0 ist dann waren alle B5 Bytes 0
        If($Sum -eq 0) {
            # ausgabe des Datei-Pfades
            $File
        }
    }

    Dieser Code ist auf Geschwindigkeit Optimiert.
    Da alle 4mil Dateinamen in den Speicher geladen werden, braucht der Code ein bisschen mehr RAM Speicherplatz!

    Siehe meinen Artikel :

    PowerShell ForEach und ForEach-Object
    http://www.admin-source.de/BlogDeu/905/powershell-foreach-und-foreach-object


    PowerShell Artikel, Buchtipps und kostenlose PowerShell Tutorials + E-Books
    auf der deutschsprachigen PowerShell Community

    Mein 21 Teiliger PowerShell Video Grundlehrgang
    Deutsche PowerShell Videos auf Youtube
    Folge mir auf:
    Twitter | Facebook | Google+

    Mittwoch, 16. April 2014 06:00
  • param(
    [Parameter(Mandatory=$True,Position=1)]
     [string]$Quelle,
    [Parameter(Mandatory=$True,Position=2)]
     [string]$Logausgabe
    )
    
    write-Host Das Verzeichnis und Unterverzecihnisse werden geprüft: $Quelle
    write-Host $LogAusgabe
    Get-ChildItem $Quelle -Filter *-* -rec | ForEach-Object {
        $Path = $_.Fullname
        $Sum = Invoke-Expression ((Get-Content -Path $Path -Encoding byte -ReadCount 5 -TotalCount 5) -join '+')
        If($Sum -eq 0){
    		$Path |out-file -filepath $LogAusgabe -width 1000 -append
    		}
    }

    Ich habe das Script für meine Bedürfnisse verändert und getestet.
    Danke


    • Als Antwort markiert Alex Pitulice Mittwoch, 23. April 2014 14:56
    Mittwoch, 16. April 2014 14:58

Alle Antworten