jenny82
Goto Top

Powershell multiple Datei-Inhaltssuche und mehrere Unterordner

Hallo zusammen,

ich versuche gerade per Powershell Dateien mit bestimmtem Textinhalt in diverse Unterordner zu verschieben und krieg das nicht hin.

Die Dateien haben nur eine Zeile und ca. 100.000 Zeichen.
Sofern möglich, sollten deshalb nur die ersten 2000 Zeichen eingelesen werden, damit er nicht bis zum Ende der Datei sucht.
Innerhalb der Dateien kann immer nur ein Ergebnis vorkommen.

Der Grundaufbau habe ich mir in etwa so gedacht:


$quellen = 'quelle1;quelle2;quelle3;quelle...'

$filter = '*xyz*.*'

$Suche
'*Textsuche1*'
'*Textsuche2*'
'*Textsuche3*'
'*Textsuche4*'
'*Textsuche5*'
'*Textsuche6*'

$mapSuche = @{
'*Textsuche1*' = 'Unterordner A'
'*Textsuche2*' = 'Unterordner A'
'*Textsuche3*' = 'Unterordner B'
'*Textsuche4*' = 'Unterordner B'
'*Textsuche5*' = 'Unterordner C'
'*Textsuche6*' = 'Unterordner C'
}

$quellen.split(';') | %{$quelle=$_; gci $_ $filter | ?{(gc $_.FullName -ReadCount 1000) -like $Suche} | move-item -Destination ($quelle + $($mapSuche.($Suche) -Force}


Was mir fehlt ist also eine Lösung, der die einzelnen Suchen aufteilt, den auszulesenden Inhalt auf 2000 Zeichen beschränkt und ob das dann so mit "move-item -Destination ($quelle + $($mapSuche.($Suche)" funktioniert bin ich mir auch nicht sicher.

Wäre super wenn mir da jemand helfen könnte!

Gruß Jenny

Content-ID: 318562

Url: https://administrator.de/contentid/318562

Ausgedruckt am: 25.11.2024 um 08:11 Uhr

colinardo
colinardo 20.10.2016 um 19:11:50 Uhr
Goto Top
Hallo Jenny,
wie immer gibt's mehrere Wege nach Rom. Such dir einen aus:

back-to-topWeg 1
(Keine Sternchen in den Suchworten verwenden hier wird per regex gematcht da braucht es diese nicht)
$quellen = "C:\Folder1","C:\Folder2"  
$filter = "*.txt"  

$mapSuche = @{
'Textsuche1' = 'Unterordner A'  
'Textsuche2' = 'Unterordner B'  
'Textsuche3' = 'Unterordner B'  
'Textsuche4' = 'Unterordner B'  
'Textsuche5' = 'Unterordner C'  
'Textsuche6' = 'Unterordner C'  
}
$match = (($mapSuche.GetEnumerator().Name | %{[regex]::Escape($_)}) -join '|')  

$quellen | %{
    gci $_ -Filter $filter | group {[regex]::match((@(gc $_.Fullname)[0..1999] -join ''),"(?i)$match")} | %{  
        $dest = "$($_.Group.DirectoryName)\$($mapSuche.([regex]::Unescape($_.Name)))"  
        if(!(Test-Path $dest)){md $dest -Force | out-null}
        $_.Group | move-item -Destination $dest
    }
}

back-to-topWeg 2
$quellen = "C:\Folder1","C:\Folder2"  
$filter = "*.txt"  

$mapSuche = @{
'*Textsuche1*' = 'Unterordner A'  
'*Textsuche2*' = 'Unterordner B'  
'*Textsuche3*' = 'Unterordner B'  
'*Textsuche4*' = 'Unterordner B'  
'*Textsuche5*' = 'Unterordner C'  
'*Textsuche6*' = 'Unterordner C'  
}

$quellen | %{
    gci $_ -Filter $filter -PipelineVariable file | %{
        [string]$content = @(gc $_.Fullname)[0..1999] -join ''  
        $mapSuche.GetEnumerator() | ?{$content -like $_.Key} | %{
            $dest = "$($file.DirectoryName)\$($mapSuche.($_.Key))"  
            if(!(Test-Path $dest)){md $dest -Force | out-null}
            $file | move-item -Destination $dest -Force
            return
       }
    }
}
Grüße Uwe
Jenny82
Jenny82 24.10.2016 um 13:27:07 Uhr
Goto Top
Hallo Uwe,

vielen Dank für die schnelle Hilfe.

Variante 1 wirft keine Fehler, macht aber irgendwie auch nichts (die Sternchen hab ich in der Suche weggelassen).

Variante 2, die ich persönlich bevorzugen würde, wirft folgenden Fehler:
Get-ChildItem : Es wurde kein Parameter gefunden, der dem Parameternamen "PipelineVariable" entspricht.
Bei Zeile:10 Zeichen:45

back-to-topgci $_ -Filter $filter -PipelineVariable <<<< file | %{

+ CategoryInfo : InvalidArgument: (face-smile [Get-ChildItem], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

Grüße Jenny
colinardo
colinardo 24.10.2016 aktualisiert um 13:47:41 Uhr
Goto Top
Variante 2 benötigt bei der Verwendung des Pipelinevariable Parameters min. PS 3.0. Du kannst es aber auch ohne die Pipeline-Variable machen indem du innerhalb der äußeren Schleife einfach eine Variable definerst also zw. Zeile 14 und 15 einfach noch folgende einfügst:
$file = $_
und das -PipelineVariable file weglässt.

Beide Variante laufen hier wie immer einwandfrei! Du wirst sie nur nicht richtig angewendet haben.

Brauchst du noch mehr Support von meiner Seite, via PM anklingeln, dann kommt Angebot pronto.

Grüße Uwe