【问题标题】:"Unix shell"-alike script under WindowsWindows下的“Unix shell”类似脚本
【发布时间】:2010-09-16 02:18:01
【问题描述】:

我需要一些 shell 脚本专家的帮助。

我有一个 .txt 文件(日志),它在多行上跟踪客户端的 IP 地址,格式与此类似:

Line1 - Client IP [192.168.0.1] Other data
Line2 - Client IP [192.168.0.2] Other data
Line3 - Client IP [192.168.0.3] Other data
Line4 - Client IP [192.168.0.2] Other data
Line5 - Client IP [192.168.0.1] Other data
...

我需要创建以下脚本:

  • 从此文件中提取 IP 地址
  • 对 IP 地址进行分组(同一个 IP 地址只报告一次)
  • 使用生成的 IP 地址输出文件

对于前面的示例,生成的文件将是:

192.168.0.1
192.168.0.2
192.168.0.3

我使用的是 Windows 操作系统,但我可以使用 CygwinUnix Tools 之类的工具(在 Windows 下提供类似 Unix 的命令,如 grep、sort 等)。

没有脚本的解决方案也可以。

提前感谢您的帮助。

【问题讨论】:

  • 如果您必须在 Windows 平台上编写大量脚本,您应该查看 PowerShell。它很容易学习,在 Windows 平台上几乎没有什么是你不能用它做的。

标签: windows unix shell scripting


【解决方案1】:
 cat yourfile.txt | sed 's/*\[//g' | sed 's/\]*//g' | sort | uniq > newfile.txt

括号可能不需要转义符。我不记得了。这些工具应该都可以在 Cygwin 上使用。

【讨论】:

    【解决方案2】:

    这是一个简短的 sed 脚本,它提取方括号之间的部分,然后 sort -u 删除重复项:

    sed -e 's/^.*\[\(.*\)\].*$/\1/g' < inputfile | sort -u
    

    【讨论】:

      【解决方案3】:

      在 PowerShell 中:

      详细方式 -

      $regex = '(?<IPAddress>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
      get-content log.txt | where-object {if ($_ -match $regex){$matches.ipaddress}} | group-object -noelement
      

      短版

      gc log.txt | % {if ($_ -match $regex){$matches.ipaddress}} | group -n
      

      【讨论】:

        【解决方案4】:

        为了简洁,很难击败那些 sed 脚本。好吧,可读性是个问题……

        您可以使用 Scripting.FileSystemObject 进行文件访问,使用 VBScript 的正则表达式和 Dictionary 对象,在 VBScript 中做一个更详细,也许更易读的版本,如下所示。

        Option Explicit
        
        Dim oFSO
        Dim oRgx
        Dim oMatch
        Dim oMatches
        Dim oStream
        Dim sLine
        Dim oDict
        Dim sIP
        Dim aKeys
        Dim sKey
        
        Set oFSO     = CreateObject( "Scripting.FileSystemObject" )
        Set oDict    = CreateObject( "Scripting.Dictionary" )
        
        Set oStream  = oFSO.OpenTextFile( "log.txt", 1, False )
        
        Set oRgx     = new regexp
        oRgx.Pattern = "\[(.+?)\]"
        oRgx.Global  = True
        
        Do While Not oStream.AtEndOfStream
          sLine        = oStream.ReadLine
          Set oMatches = oRgx.Execute(sLine)
        
          For Each omatch in omatches
            sIP         = oMatch.SubMatches(0)
        
            If Not oDict.Exists( sIP ) Then
              oDict.Add sIp,1
            End If
        
          Next
        
        Loop
        
        aKeys = oDict.Keys
        
        For Each sKey in aKeys
          wscript.echo sKey
        Next
        

        【讨论】:

          【解决方案5】:

          如果您可以使用 Cygwin,则无需担心 Windows 脚本解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多