L’une des premières commandes Linux que de nombreux administrateurs système apprennent est grep. Cet outil vénérable existe depuis des décennies et est crucial pour la ceinture d’outils de tout administrateur. Le cœur de Grep est simplement la capacité de rechercher un motif RegEx dans du texte brut. Grep peut rechercher des fichiers dans un répertoire donné ou des entrées en continu pour obtenir des correspondances en sortie. Saviez-vous que PowerShell dispose de Grep ? Eh bien…presque.
PowerShell, étant un langage, est plus qu’un simple binaire à usage unique. Par conséquent, quelles capacités intégrées existent pour rechercher du texte brut en utilisant des motifs RegEx un peu comme le fait grep ? Dans cet article, nous explorons les innombrables façons de rechercher du texte dans des fichiers à l’aide de PowerShell.
Exploration du cmdlet Select-String
Select-String
(notre grep PowerShell) travaille sur des lignes de texte et, par défaut, recherche la première correspondance dans chaque ligne, puis affiche le nom du fichier, le numéro de ligne et le texte dans la ligne correspondante. En outre, Select-String
peut travailler avec différents encodages de fichiers, tels que le texte Unicode, en utilisant le byte-order-mark (BOM) pour déterminer le format d’encodage. Si le BOM est absent, Select-String
supposera qu’il s’agit d’un fichier UTF8.
Paramètres de Select-String
-
AllMatches
– Normalement,Select-String
ne cherchera que la première correspondance dans chaque ligne, en utilisant ce paramètre, le cmdlet cherchera plus d’une correspondance. Un seul objetMatchInfo
sera toujours émis pour chaque ligne, mais il contiendra toutes les correspondances trouvées. -
CaseSensitive
– Les correspondances ne sont pas sensibles à la casse par défaut, cela force le cmdlet à rechercher les correspondances qui correspondent exactement au motif d’entrée. -
Context
– Un paramètre très utile en ce que, vous pouvez définir le nombre de lignes avant et après la correspondance qui seront affichées. L’ajout de ce paramètre modifie l’objetMatchInfo
émis pour inclure une nouvelle propriétéContext
qui contient les lignes spécifiées.
N’oubliez pas que si vous pipez la sortie de
Select-String
vers un autre appelSelect-String
, le contexte ne sera pas disponible puisque vous ne recherchez que sur l’unique propriété résultanteMatchInfo
line
.
-
Culture
– Utilisé avec le paramètreSimpleMatch
, ceci spécifie une culture à faire correspondre avec le motif spécifié. Cela inclut des options telles queen-US
es
, oufr-FR
à titre d’exemple. Quelques autres options utiles sont les optionsOrdinal
etInvariant
Ordinal
est pour les comparaisons binaires non linguistiques etInvariant
est pour les comparaisons indépendantes de la culture.
Ce paramètre a été introduit dans PowerShell 7 et n’est pas disponible pour les versions antérieures. Gardez également à l’esprit que cela utilisera la culture actuelle du système, par défaut, qui peut être trouvée en utilisant
Get-Culture
.
-
Encoding
– Spécifie l’encodage du fichier cible à rechercher, qui est par défaututf8NoBOM
.-
ascii
: Utilise l’encodage pour le jeu de caractères ASCII (7 bits). -
bigendianunicode
: Encode au format UTF-16 en utilisant l’ordre des octets big-endian. -
oem
: Utilise l’encodage par défaut pour les programmes MS-DOS et console. -
unicode
: Encode au format UTF-16 en utilisant l’ordre des octets little-endian. -
utf7
: Encode au format UTF-7. -
utf8
: Encode au format UTF-8. -
utf8BOM
: Encode au format UTF-8 avec la marque d’ordre des octets (BOM) -
utf8NoBOM
: Encode au format UTF-8 sans marque d’ordre des octets (BOM) -
utf32
: Encode au format UTF-32.
À partir de PowerShell Core 6.2, le paramètre
Encoding
accepte également les identifiants numériques des pages de code enregistrées tels que1251
ou les noms de chaîne tels quewindows-1251
. -
A partir de PowerShell Core 6.2, le paramètre
Encoding
accepte également les identifiants numériques des pages de code enregistrées tels que1251
ou les noms de chaîne tels quewindows-1251
.
-
Exclude
– En travaillant avec le paramètrePath
, excluez des éléments spécifiques en utilisant un motif, tel que*.txt
. -
Include
– Tout comme le paramètreExclude
Include
inclura uniquement les éléments spécifiés à l’aide d’un motif, comme*.log
. -
List
– Renvoie uniquement la première instance du texte correspondant de chaque fichier d’entrée. Ceci est destiné à être un moyen rapide et efficace de récupérer une liste de fichiers dont le contenu correspond. -
LiteralPath
– Ceci indique àSelect-String
d’utiliser les valeurs en entrée, au lieu d’interpréter des valeurs telles que*
comme un caractère générique. Si le chemin d’accès comprend des caractères d’échappement, mettez-les entre guillemets simples pour ne faire aucune interprétation. -
NoEmphasis
– Au lieu de mettre en évidence la chaîne sur laquelle le motif est apparié, désactivez la mise en évidence des correspondances. Par défaut, la mise en évidence utilise des couleurs négatives basées sur les couleurs du texte d’arrière-plan. -
NotMatch
– Recherchez le texte qui ne correspond pas au motif spécifié. -
Path
– Spécifiez le chemin d’accès aux fichiers à rechercher. Les caractères génériques sont autorisés, mais vous ne pouvez pas spécifier uniquement un répertoire. La valeur par défaut est le répertoire local. -
Pattern
– Le motif à rechercher dans le contenu ou les fichiers d’entrée sur la base de RegEx. -
SimpleMatch
– Utiliser une correspondance simple au lieu des expressions régulières. Puisque RegEx n’est pas utilisé, l’objetMatchInfo
retourné ne possède aucune valeur dans la propriétéMatches
. -
Raw
– Sortir les chaînes de caractères correspondantes, sans objetMatchInfo
. C’est le comportement qui se rapproche le plus degrep
et non de la nature plus orientée objet de PowerShell. -
Quiet
– Ne renvoie un$true
ou$false
que si le motif est trouvé.
Utilisation de PowerShell Grep err… Select-String
Bien sûr, savoir comment fonctionnent les paramètres et les options d’une cmdlet n’est pas tout à fait la même chose que de l’utiliser dans un environnement de production. Plongeons dans des exemples et voyons comment nous pouvons tirer parti de Select-String
pour faciliter la recherche de correspondances de texte.
Il y a trois façons d’utiliser Select-String
pour trouver des correspondances.
- Pipe in quoted text to the
Select-String
cmdlet, i.e. stream in the text. - En utilisant le texte stocké dans une variable, passez la variable au paramètre
InputObject
. - Utilisez le paramètre
Path
pour spécifier les fichiers dans lesquels rechercher le texte.
Les fichiers que nous utilisons pour tester ceci sont des contenus générés aléatoirement, mais du même type que ceux que l’on trouve souvent dans les systèmes de production.
Mise en correspondance simple dans des fichiers
Démarrons avec un exemple très simple, recherchons Joe
dans une poignée de fichiers CSV.
Select-String -Path "Users\*.csv" -Pattern "Joe"
Comme vous pouvez le voir, c’est assez simple, on voit comment Joe
est mis en évidence sur la ligne avec le reste des données. Mais quelles sont les données qui sont réellement renvoyées ici ? Jetons un coup d’œil à toutes les propriétés d’une correspondance retournée.
Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object * -First 1
Nous avons ici quelques propriétés qui sont utiles. Notamment les line
path
pattern
, et matches
. La plupart de ce que nous voulons savoir se trouve dans la propriété matches
.
Select-String -Path "Users\*.csv" -Pattern "Joe" | Select-Object -ExpandProperty Matches -First 1
Vous pouvez voir ici comment, même si nous avons utilisé une expression simple, il s’agit toujours d’une expression RegEx et des détails ultérieurs disponibles.
Et si nous recherchions plusieurs valeurs différentes en utilisant des motifs séparés par des virgules ? C’est utile car cela définit en fait trois motifs différents et non une valeur RegEx complexe.
Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry"
Vous pouvez voir comment c’est le cas, si nous sélectionnons uniquement les filename
pattern
, et line
de notre recherche.
Select-String -Path "Users\*.csv" -Pattern "Joe","Marti","Jerry" | Select-Object FileName, Pattern, Line
Mise en correspondance RegEx plus complexe
Maintenant que nous avons démontré certaines des méthodes de mise en correspondance les plus simples, que diriez-vous d’utiliser davantage RegEx pour rechercher réellement des motifs plus utiles ? Les trois exemples ici recherchent des adresses de courriel, des adresses IP et des numéros de sécurité sociale (SSN). Les modèles utilisés ici ne sont pas la seule façon de construire une recherche RegEx, et il existe peut-être des moyens plus simples. PowerShell Grep (Select-String) est une cmdlet assez avancée.
Voyons si des emails sont contenus dans nos fichiers. L’utilisation d’une correspondance RegEx quelque peu complexe, comme indiqué ci-dessous, démontrera la recherche de ces correspondances.
Select-String -Path "Users\*.csv" -Pattern '\\b+\.{2,4}\b' | Select-Object -First 10
Bien sûr, plus préoccupant pourrait être si des SSN étaient inclus dans un fichier. Une correspondance très simple pour cela serait la suivante.
Select-String -Path "Users\*.csv" -Pattern '\d\d\d-\d\d-\d\d\d\d' | Select-Object -First 10
Enfin, et si nous voulions rechercher des adresses IP dans notre fichier ? L’utilisation d’une autre expression RegEx pour rechercher ce motif, fait un travail rapide.
Select-String -Path "Users\*.csv" -Pattern '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' | Select-Object -First 10
Une mise en garde concernant cette RegEx. Techniquement, cela correspondra à des valeurs jusqu’à 999.999.999.999
qui est une IP invalide. Vous pouvez construire des expressions RegEx plus précises qui seront plus longues, mais c’est un compromis en fonction de ce que vous cherchez à faire.
Recherche avec le contexte
Le contexte est très utile dans le dépannage, il permet d’expliquer ce qui se passe avant qu’un événement se produise et après. Par exemple, faisons une recherche dans un journal Apache et trouvons ce suspendedpage.cgi
texte.
Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -First 1
Le >
simple indique la ligne appariée, et il y a une ligne avant la correspondance et après la correspondance. Dans cet exemple, cela pourrait nous indiquer que le robot Google recherchait robots.txt
et a malheureusement reçu un résultat suspendedpage.cgi
à la place. Ensuite, il est allé essayer la page d’accueil et a peut-être obtenu la même erreur.
Que contient exactement la propriété context
alors telle qu’émise par l’objet MatchInfo
? Si nous développons cette propriété, vous pouvez voir qu’il y a PreContent
et PostContent
. Cela signifie que vous pouvez manipuler cela plus loin si nécessaire.
Select-String -Path "Web\*.txt" -Pattern "suspendedpage.cgi" -Context 1 | Select-Object -ExpandProperty Context -First 1 | Format-List
D’autres exemples de recherche dans les fichiers journaux se trouvent dans des articles tels que Making Sense of the Microsoft DNS Debug Log qui démontre l’utilisation de Select-String
pour parcourir un journal de débogage DNS. Le grep de PowerShell est fort dans ce post.
Conclusion
Grep est un outil incroyablement utile dans le monde Linux, et Select-String
offre beaucoup de la même fonctionnalité dans le monde PowerShell. L’ajout de la nature orientée objet de PowerShell ne sert qu’à améliorer l’utilité et l’utilité que le cmdlet offre.
Pour de nombreux administrateurs système, être capable de rechercher rapidement et efficacement des fichiers journaux sur différents types, ainsi que de comprendre le contexte, est une capacité incroyablement importante et nécessaire. PowerShell Select-String
rend cela facile à faire et permet d’économiser d’innombrables heures de dépannage !