J'ai une application qui génère des centaines de fichiers journaux texte qui ressemblent à
GC C:\log_5.txt |
Select-String -Pattern 'Host=\"([^\"]*)\"'
Je dois sélectionner l'hôte parmi ceux-ci J'ai essayé
DaemonReruns=2| Phase=| Log=false| DS=LOG_4| Schema=LOLYY| DBMS=mssql| Host=abc.XYz.com| IDs=xxxxx,xxxx
Ne donne aucun résultat, aucune aide?
6 Réponses :
((Get-Content -Path .\log_5.txt) -match 'Host=') -replace 'Host=','' returns all the lines starting with Host=
cool , il vient avec Host = abc.domain.com | pouvons-nous exclure Host = et | juste besoin de l'url
Il n'y a pas de guillemets dans votre exemple d'entrée. Essayez cette expression régulière:
get-content C:\log_5.txt | foreach {
if ($_ -match 'Host=([^|]+)') {
$Matches.1
}
}
Remarque: Cela renvoie en fait les noms d'hôte, pas seulement la ligne.
Cool, cela fonctionne mais pas capable de trier les fichiers uniques `gci C: \ logs | où {$ _. Extension -comme '* .txt' -ou $ _. Extension -comme '* .proc'} | Foreach {Get-Content $ _. FullName} | foreach {if ($ _ -match 'Host = ([^ |] +)') {$ data = $ Matches.1 $ data | Sort-Object -Unique}} `
@Jondrew Placez le tri à la toute fin du pipeline: ... {$ Matches.1}} | sort -Unique
il ne sera pas foreach {if ($ _ -match 'Host = ([^ |] +)') {$ Matches.1 | sort -Unique}}
@Jondrew foreach {if ($ _ -match 'Host = ([^ |] +)') {$ Matches.1}} | sort -Unique
la réponse utile de marsze résout le problème avec votre regex et utilise un ForEach-Object ( foreach ) pour extraire et renvoyer des correspondances via l'opérateur -match et la variable automatique $ Matches .
Voici un résumé (et mieux -performing) à l'aide du commutateur instruction :
PS> switch -Regex -File C:\log_5.txt { 'Host=([^|]+)' { $Matches[1] } }
abc.XYz.com
Notez que -File n'accepte pas les chemins basés sur des caractères génériques, cependant, dans l'ordre pour traiter plusieurs fichiers, vous devrez les parcourir via Get-ChildItem ou Convert-Path.
Juste pour le plaisir ... la solution ultra-rapide :
$regex = [Regex]::new('Host=([^|]+)', 'Compiled, IgnoreCase, CultureInvariant')
& {foreach ($line in [IO.File]::ReadLines("C:\log_5.txt")) {
$m = $regex.Match($line)
if ($m.Success) {
$m.Groups[1].Value
}
}}
p >
Btw, il semble que ce qui ralentit switch -Regex par rapport à [regex] .Match () est l'effort supplémentaire de traduire les informations de correspondance dans les $ Matches hashtable.
@ mklement0 Ouais PS est toujours un langage de script conçu pour être facilement utilisable, pas rapide. Si j'écris la même chose en code C #, compilez-le avec Add-Type et appelez cela, c'est quelques dizaines de fois plus rapide.
Belle solution C #; autre brève tangente: voici un piège amusant avec switch -File : github. com / PowerShell / PowerShell / issues / 8988
Si vos logs sont énormes, cela pourrait valoir la surcharge de Add-Type , et le reste serait beaucoup plus rapide:
Add-Type '
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace PowerShell
{
public class Tools
{
static Regex regex = new Regex(@"Host=([^|]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
public static IEnumerable<string> GetHosts(string path)
{
foreach(var line in File.ReadLines(path))
{
var matches = regex.Match(line);
if (matches.Success)
{
yield return matches.Groups[1].Value;
}
}
}
}
}'
# call this for each log file (very fast)
[PowerShell.Tools]::GetHosts("C:\log_5.txt")
Les autres réponses traitent assez bien du côté des expressions régulières. Chaque fois que je vois de petits journaux comme celui-ci, je pense toujours à ConvertFrom-StringData qui
convertit une chaîne contenant une ou plusieurs paires clé / valeur en une table de hachage.
De: help ConvertFrom-StringData
Dans sa forme de base, nous faisons juste quelque chose comme ceci:
[pscustomobject](Get-Content -File $pathToFile | ForEach-Object{$_.trimend("|")} | Out-string | ConvertFrom-StringData)
[pscustomobject]((Get-Content -Raw -File $pathToFile) -replace "(?m)\|$" | ConvertFrom-StringData)
Ce qui vous donnerait un objet PowerShell avec lequel vous pouvez interagir facilement! p >
DS : LOG_4| Schema : LOLYY| IDs : xxxxx,xxxx Log : false| DBMS : mssql| Host : abc.XYz.com| Phase : | DaemonReruns : 2|
Vous doutez que vous ayez besoin des tuyaux de fin. Vous pouvez les supprimer avec des méthodes d'expression régulière ou de chaîne plus simples.
$pairs = Get-Content -Raw -File $pathtofile | ConvertFrom-StringData [pscustomobject]$pairs
Dans tous les cas, cela vous donne plus d'options sur la façon dont vous devez traiter vos données.