web-dev-qa-db-fra.com

Chaînes correspondantes dans PowerShell

l'essentiel de cette question est:

Il semble donc que if ($C -match $b.Name) considère une correspondance partielle d'une chaîne comme une correspondance? Existe-t-il une meilleure façon de forcer un complet [match] d'une chaîne?

J'ai un répertoire qui est rempli d'une tonne de fichiers .7z. J'ai besoin de nettoyer ce répertoire en permanence. Il y a un autre script, antérieur à mon emploi ici, qui fonctionne actuellement, mais il est composé de 3000 lignes et génère constamment des correspondances incorrectes et n'enregistre pas ce qui a été déplacé ou supprimé. Ce qui le rend si gros, c'est qu'il a une tonne de chemins pour où ces fichiers doivent être déplacés vers un code dur. Parfois, ces chemins changent et il est difficile de les mettre à jour.

J'ai donc commencé à créer un script beaucoup plus petit qui a tous ces chemins référencés dans un fichier CSV. En plus de ces chemins, le fichier CSV contient également des noms de fichiers connus.

J'essaie de faire correspondre les noms de fichiers avec les noms enregistrés dans mon fichier CSV. Cela fonctionne généralement, mais parfois j'obtiens des correspondances incorrectes.

Disons que j'ai deux fichiers qui démarrent de la même manière, Apple et Apple_Pie. Apple correspondra à Apple et passera à la le bon répertoire, mais Apple_Pie correspondra d'abord à Apple et se déplacera vers le mauvais répertoire. Avant que la variable $C soit effacée, elle fera correspondre Apple_Pie au bon répertoire, mais par cela le point Apple_Pie n'existe plus dans le répertoire d'origine dont il doit être déplacé.

Il semble donc que if ($C -match $b.Name) considère une correspondance partielle d'une chaîne comme une correspondance? Existe-t-il une meilleure façon de forcer la fin d'une chaîne?

Je suppose que je suis un peu en retrait par rapport à mes attentes sur la façon dont -match Devrait fonctionner.

Le truc regex que j'ai ici est de supprimer chaque nom de fichier de la date-heure qui est ajoutée au nom de fichier par un autre processus automatisé. J'utilise ceci pour isoler le nom de fichier que je veux faire correspondre.

$Wild = "C:\Some\Folder\With\Files\"

$CSV = "C:\Another\Folder\Paths.csv"

$Content = gci $wild

$Reg1 = [regex] '_[0-9]{4}-[0-9]{2}-[0-9]{2}[A-Z]{1}[0-9]{2}_[0-9]{2}_[0-9]{2}'

$Reg2 = [regex] '[0-9]{4}-[0-9]{2}-[0-9]{2}[A-Z]{1}[0-9]{2}_[0-9]{2}_[0-9]{2}'

$Paths = import-csv -path $CSV -header Name, Path

foreach ($a in $content) {
    $c = $a.BaseName

    if ($c -match $reg1) {
        $c = $c -replace $regyear
    }
    elseif ($c -match $reg2) {
        $c = $c -replace $reg2
    }

    foreach ($b in $Paths) {

        if ($c -match $b.Name) {
            Do something
        }
    }
}
3
Ochuse

Je pense que votre principal problème est que vous utilisez "match".

Il vérifie si la chaîne de droite fait ... partie de la chaîne de gauche, pas si c'est une correspondance réelle comme vous vous en doutez.

$a = "Test"
$b = "Test_me"

$a -match $b
False

$b -match $a
True

Je remplacerais -match avec -like.

1
BlueBunny