Question Fractionnement chaine caractère

Plus d'informations
il y a 2 ans 9 mois - il y a 2 ans 9 mois #30896 par witness
Bonjour,Dans un script que vous trouverez ci-dessous, je cherche à mapper des imprimantes à partir d'un fichier .txt dans lequel se trouve ligne par ligne le nom de l'ordinateur ainsi que l'imprimante à mapper.
Pour l'exemple et afin que ce soit plus clair, voici quelques lignes que contient mon fichier txt:

s202-01:\\server\imp-s202
s202-02:\\server\imp-s202
s202-03:\\server\imp-s202
s202-04:\\server\imp-s202
s202-05:\\server\imp-s202

Nous avons le nom de l'ordinateur en premier puis le chemin de l'imprimante à mapper.

Voici mon script:

$computername=$env:computername
$Printerslist=Get-Content C:\POWERSHELL\imprimantes.rtf
$Printername="Imp-" + $computername -split "-"

ForEach ($print in $Printerslist) $print
    {
If($_.$Printerslist -like $computername) 
{ 
    (New-Object -ComObject WScript.Network).AddWindowsPrinterConnection("\\0570313f-data\$printername")
}
else
{
    Write-Output "Il n'y a pas d'imprimante avec le nom Imp-"
}
    }

Au niveau de la ligne $Printername, ce que j'aimerais faire c'est recomposer le nom de l'imprimante à partir d'un préfixe toujours valable "Imp-" suivi d'une partie du nom de l'ordinateur, à savoir, par exemple, pour la première ligne de mon fichier txt, le début du nom de l'ordinateur jusqu'au -

Ainsi, si je reprends la première ligne de mon fichier txt, le nom de mon imprimante devrait être, une fois recomposée, Imp-s202.
Merci.
Dernière édition: il y a 2 ans 9 mois par witness.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 9 mois - il y a 2 ans 9 mois #30897 par Arnaud Petitjean
Bonjour Witness57,

Je vois qu'il y a quelques petites erreurs dans ton script, comme :
- $print qui traine à la fin de ta ligne foreach => à retirer
- utilisation de $_ dans ton traitement => utiliser $print à la place

Question : pourquoi essayer de recomposer le nom de ton imprimante alors que tu l'as dans ton fichier ? Il suffit d'aller le chercher dedans, non ?

Pour faciliter la compréhension de ton besoin, est-ce que tu pourrais mettre en face de chaque ligne de ton fichier source, le résultat attendu ?

Merci
PS : Une dernière chose, il existe une balise spécifique pour insérer du code dans un Post du forum. Utilise la STP. Il s'agit de la balise Code matérialisée par l'icone <>

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Dernière édition: il y a 2 ans 9 mois par Arnaud Petitjean.
Les utilisateur(s) suivant ont remercié: witness

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 9 mois - il y a 2 ans 9 mois #30903 par witness
Réponse de witness sur le sujet Fractionnement chaine caractère
Bonjour Arnaud,

Merci pour ton aide.

Concernant la variable $print, si je comprends bien, bien qu'elle ne soit pas déclarée explicitement comme les autres variables, du moment qu'elle est dans ForEach, elle devient une variable réutilisable ?
Mais dans ce cas, elle est réutilisable que dans le bloc d'instruction ForEach ou bien reste-elle valable pour tout le script comme les variables explicitement déclarée ?

Pour le nom de l'imprimante, en effet, je ne suis pas obligé de le recomposer puisqu'il est dans le fichier, mais dans ce cas il faut que je récupère la partie de la ligne qui contient ce nom

Merci.
Dernière édition: il y a 2 ans 9 mois par witness.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 9 mois #30904 par Arnaud Petitjean
Hello Witness du 57 !

Concernant la variable $print, si je comprends bien, bien qu'elle ne soit pas déclarée explicitement comme les autres variables, du moment qu'elle est dans ForEach, elle devient une variable réutilisable ?

Oui, c'est exact. Ta variable devient utilisable uniquement dans ta boucle Foreach. Elle contiendra un élément à un instant t de ta collection.

Mais dans ce cas, elle est réutilisable que dans le bloc d'instruction ForEach ou bien reste-elle valable pour tout le script comme les variables explicitement déclarée ?

Sorti de ton bloc Foreach, cette variable n'existera plus. On dit que sa portée se limite au bloc ForEach.

Concernant le nom de ton imprimante, alors on essaye de se l'extraire de ton fichier ? 

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 9 mois - il y a 2 ans 9 mois #30906 par Arnaud Petitjean
Concernant l'extraction du nom de ton serveur dans ta chaine, c'est là que ça devient rigolo ;-) !
En tout cas moi ça m'amuse et je prend ça comme un jeu.

On peut le faire de plusieurs façons différentes. Soit en éclatant la chaine, soit en utilisant une expression régulière.

Je vais te montrer les deux techniques. Commençons par la première :

# Avant d'attaquer en frontal ton fichier, on va déjà s'exercer sur une simple chaine de texte
$str = 's202-01:\\server\imp-s202'
$imp = ($str -split '\\')[-1]

$imp

imp-s202

Ici, on a éclaté la chaine sur le backslash. J'ai dû en mettre deux car l'opérateur -Split attend une expression régulière. En en langage des expressions régulières un backslash a une signification particulière.
Ensuite PowerShell nous retourne un tableau. Et donc on va chercher l'index -1, c'est à dire la dernière case de notre tableau; celle dans laquelle se trouve la donnée qui nous intéresse.

A présent passons avec la seconde technique; celle avec des expressions régulières pures. Là c'est une toute autre paire de manches; mais ça devient intéressant si on se prend au jeu.

$str = 's202-01:\\server\imp-s202'
$str -match '.+\:\\\\(?<servername>.+)\\(?<printername>.+)'
$imp = $matches.printername

$imp

imp-s202

Disclaimer : Je ne suis pas expert en RegEx et je suis sûr qu'il est possible de faire mieux. Merci de ne pas me jeter la pierre ;-)


Une expression régulière (où RegEx pour les intimes) est un pattern que l'on essaie de faire correspondre (matcher) avec une chaine de caractère. C'est un langage très puissant qui fait régulièrement l'objet de livres entiers; donc c'est normal si tu as du mal à la comprendre ;-) Surtout si c'est ta première :-P.

Ici la RegEx que j'ai créé reflète la chaine contenue dans $str. En gros, on récupère tous les caractères jusqu'au 1er : suivi des deux backslashs, suivis à leur tour par une chaine de caractères suivie d'un dernier backslash, suivi encore une fois d'une chaine de caractères (ouf !).

Les parenthèses indiquent une capture; c'est à dire qu'on va récupérer cette sous chaine. En plus on va nommer la capture grâce à la syntaxe ?<NomDeLaCapture>.

Si la RegEx a fonctionné l'opérateur -Match retourne $true, sinon $false.
Si on obtient $true, cela peuple la variable $Matches. Celle-ci est un tableau associatif (ou hashtable) qui contiendra les données capturées.

Exemple : 
# retourne le nom de l'imprimante
$matches.printername 

# retourne le nom du serveur
$matches.servername

Voilà ;-)



 

MVP PowerShell et créateur de ce magnifique forum :-)
Auteur de 6 livres PowerShell aux éditions ENI
Fondateur de la société Start-Scripting
Besoin d'une formation PowerShell ?
Dernière édition: il y a 2 ans 9 mois par Arnaud Petitjean.

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 2 ans 9 mois - il y a 2 ans 9 mois #30911 par witness
Réponse de witness sur le sujet Fractionnement chaine caractère


Je vais te montrer les deux techniques. Commençons par la première :


# Avant d'attaquer en frontal ton fichier, on va déjà s'exercer sur une simple chaine de texte
$str = 's202-01:\\server\imp-s202'
$imp = ($str -split '\\')[-1]

$imp

imp-s202


Ici, on a éclaté la chaine sur le backslash. J'ai dû en mettre deux car l'opérateur -Split attend une expression régulière. En en langage des expressions régulières un backslash a une signification particulière.
Ensuite PowerShell nous retourne un tableau. Et donc on va chercher l'index -1, c'est à dire la dernière case de notre tableau; celle dans laquelle se trouve la donnée qui nous intéresse.


En faisant divers tests en modifiant le [-1] j'obtiens:

[0] = s202-01:
[1] = rien
[2] = server
[3] = imp-s202

On peut mettre [3] plutôt que [-1] du coup ?

Pourquoi quand je mets [1] ça ne me renvoie rien ? J'aurais pensé qu'à la position [1] du tableau il y aurait la deuxième partie du fractionnement, vu que l'index commence à la position [0] ?

Pour le backslash et les expressions régulières j'ai effectivement regardé dans ton livre, à la page 577 c'est expliqué > / Fait correspond le caractère qui suit comme un caractère d'échappement".
Donc ça veut dire que par défaut, l'opérateur -split n'attend que des expressions régulières ?

Merci encore 
Dernière édition: il y a 2 ans 9 mois par witness.

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.091 secondes
Propulsé par Kunena