Выберите имена хостов из файлов журнала - PullRequest
0 голосов
/ 26 февраля 2019

У меня есть приложение, которое генерирует сотни текстовых файлов журнала, которые похожи на

DaemonReruns=2|

Phase=|

Log=false|
DS=LOG_4|
Schema=LOLYY|
DBMS=mssql|
Host=abc.XYz.com|
IDs=xxxxx,xxxx

Мне нужно выбрать хост из этих я пробовал

GC  C:\log_5.txt |
    Select-String -Pattern 'Host=\"([^\"]*)\"'

Не дает результатов, никакой помощи

Ответы [ 6 ]

0 голосов
/ 26 февраля 2019

В других ответах сторона регулярного выражения достаточно хорошо освещена.Всякий раз, когда я вижу такие маленькие журналы, как я, я всегда думаю о ConvertFrom-StringData, который

преобразует строку, содержащую одну или несколько пар ключ и значение, в хэш-таблицу.

From: help ConvertFrom-StringData

В своей базовой форме мы просто делаем что-то вроде этого:

$pairs = Get-Content -Raw -File $pathtofile | ConvertFrom-StringData
[pscustomobject]$pairs

Что даст вам объект PowerShell, с которым вы можете взаимодействоватьлегко!

DS           : LOG_4|
Schema       : LOLYY|
IDs          : xxxxx,xxxx
Log          : false|
DBMS         : mssql|
Host         : abc.XYz.com|
Phase        : |
DaemonReruns : 2|

Сомнительно, что вам нужны висячие трубы.Вы можете удалить их с помощью некоторых регулярных выражений или более простых строковых методов.

[pscustomobject](Get-Content -File $pathToFile | ForEach-Object{$_.trimend("|")} | Out-string | ConvertFrom-StringData)

[pscustomobject]((Get-Content -Raw -File $pathToFile) -replace "(?m)\|$" | ConvertFrom-StringData)

В любом случае это дает вам больше возможностей для обработки ваших данных.

0 голосов
/ 26 февраля 2019

Если ваши журналы огромны, это может стоить Add-Type, а остальное будет намного быстрее:

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")
0 голосов
/ 26 февраля 2019

Просто для удовольствия ... сверхбыстрое решение:

$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
    }
}}
0 голосов
/ 26 февраля 2019

полезный ответ Марша исправляет проблему с вашим регулярным выражением и использует вызов ForEach-Object (foreach) для извлечения и возврата совпадений с помощью оператора -match и автоматической переменной $Matches.

Вот краткая (и более эффективная) альтернатива, использующая оператор switch :

PS> switch -Regex -File C:\log_5.txt { 'Host=([^|]+)' { $Matches[1] } }
abc.XYz.com

Обратите внимание, что -File не принимает пути на основе подстановочных знаковтем не менее, чтобы обработать несколько файлов, вам придется их зациклить с помощью Get-ChildItem или Convert-Path.

0 голосов
/ 26 февраля 2019

В вашем примере нет кавычек.Попробуйте это регулярное выражение:

get-content C:\log_5.txt | foreach {
    if ($_ -match 'Host=([^|]+)') {
        $Matches.1
    }
}

Примечание. Это фактически возвращает имена хостов, а не только строку.

0 голосов
/ 26 февраля 2019
((Get-Content -Path .\log_5.txt) -match 'Host=') -replace 'Host=',''

возвращает все строки, начинающиеся с Host=

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...