【问题标题】:Select host names from log files从日志文件中选择主机名
【发布时间】:2019-02-26 14:30:08
【问题描述】:

我有一个应用程序可以生成 100 个类似的文本日志文件

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=\"([^\"]*)\"'

没有结果,有什么帮助吗?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    您的示例输入中没有任何引号。试试这个正则表达式:

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

    注意:这实际上返回主机名,而不仅仅是行。

    【讨论】:

    • 酷,它可以工作,但无法排序唯一的`gci C:\logs| where{$_.Extension -like '*.txt' -or $_.Extension -like '*.proc'} |Foreach{Get-Content $_.FullName}| foreach { if ($_ -match 'Host=([^|]+)') { $data=$Matches.1 $data|Sort-Object -Unique } } `
    • @Jondrew 将排序放在管道的最后:... { $Matches.1 } } | sort -Unique
    • 不会foreach { if ($_ -match 'Host=([^|]+)') { $Matches.1 | sort -Unique } }
    • @Jondrew foreach { if ($_ -match 'Host=([^|]+)') { $Matches.1 } } | sort -Unique
    【解决方案2】:

    marsze's helpful answer 解决了您的正则表达式问题,并使用ForEach-Object (foreach) 调用通过-match 运算符和自动$Matches 变量提取并返回匹配项。

    这是使用switch statement 的简洁(且性能更好)的替代方案:

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

    请注意,-File 不接受基于通配符的路径,但是,为了处理多个文件,您必须通过 Get-ChildItemConvert-Path 循环遍历它们。

    【讨论】:

      【解决方案3】:
      ((Get-Content -Path .\log_5.txt) -match 'Host=') -replace 'Host=',''
      

      返回所有以Host=开头的行

      【讨论】:

      • 酷,它带有 Host=abc.domain.com|我们可以排除 Host= 和 |只需要网址
      【解决方案4】:

      只是为了好玩......super-fast 解决方案:

      $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
          }
      }}
      

      【讨论】:

      • 顺便说一句,似乎使switch -Regex 相对于[regex].Match() 变慢的是额外的努力将匹配信息转换为$Matches 哈希表。
      • @mklement0 是的 PS 仍然是一种易于使用的脚本语言,而不是快速。如果我在 C# 代码中编写相同的代码,使用 Add-Type 编译它并调用它,它会快几十倍。
      • 不错的 C# 解决方案;另一个简短的切线:这是switch -File的一个有趣的陷阱:github.com/PowerShell/PowerShell/issues/8988
      【解决方案5】:

      如果您的日志很大,那么 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")
      

      【讨论】:

        【解决方案6】:

        其他答案已经很好地涵盖了正则表达式方面。每当我看到这样的小日志时,我总是会想到 ConvertFrom-StringData 哪个

        将包含一个或多个键值对的字符串转换为哈希表。

        来自:帮助 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)
        

        无论如何,这为您提供了更多关于如何处理数据的选择。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-03-12
          • 1970-01-01
          • 2019-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-04
          相关资源
          最近更新 更多