【问题标题】:Powershell look for a string between two stringPowershell 在两个字符串之间寻找一个字符串
【发布时间】:2021-03-13 12:58:29
【问题描述】:

我如何检查我的其他两个“值”之间是否存在“数据”值,知道它们之间的行数不规则并且最后一个“数据”之后没有“值”?

values
xxx
xxx
data
xxx
values
xxx
xxx
values
xxx
data
values
xxx
data
xxx

我只有:

    if (xxx) {
        xxx | Add-Content -Path $DATA
    } else {
        Add-Content -Path $DATA -Value 'N/A'
    }

最后我想要的结果是:

data
N/A
data
data

【问题讨论】:

    标签: string powershell txt


    【解决方案1】:

    您需要逐行阅读,并跟踪 1) 当您看到 values 行时和 2) 当您看到 data 行时。

    对于这种自上而下的解析,我更喜欢switch 语句:

    # In real life you would probably read from a file on disk, ie.
    # $data = Get-Content some\file.txt
    $data = -split 'values xxx xxx data xxx values xxx xxx values xxx data values xxx data xxx'
    
    # Use this to keep track of whether the first "values" line has been observed 
    $inValues = $false
    
    # Use this to keep track of whether a "data" line has been observed since last "values" line
    $hasData = $false
    
    switch($data)
    {
      'values' {
        # don't output anything the first time we see `values`
        if($inValues){
          if($hasData){
            'data'
          } else {
            'N/A'
          }
        }
        
        $inValues = $true
        # reset our 'data' monitor
        $hasData = $false
      }
    
      'data' {
        # we got one!
        $hasData = $true
      }
    }
    
    if($inValues){
      # remember to output for the last `values` block
      if($hasData){
        'data'
      } else {
        'N/A'
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用Select-String 方法:

      # $s contains a single string of your data
      ($s | Select-String -Pattern '(?s)(?<=values).*?(?=values|$)' -AllMatches).Matches.Value |
          Foreach-Object {
              ('N/A',$matches.0)[$_ -match 'data']
          }
      

      说明:

      -Pattern 没有-SimpleMatch 使用正则表达式。 (?s) 是一个单行修饰符,以便 . 匹配换行符。 (?&lt;=values) 是字符串 values 的正面回溯。 (?=values|$) 是字符串 values 或 (|) 字符串结尾 ($) 的正向前瞻。使用lookaheads 和lookbehinds 可以防止values 被匹配,以便每个都可以在下一组匹配中使用。否则,一旦values 被匹配,就不能在另一个匹配条件下再次使用。 .*? 惰性匹配所有字符。

      Foreach-Object 中,检查当前匹配对象$_ 是否存在data。如果找到data,自动变量$matches 将更新其值。由于$matches是一个哈希表,所以需要访问捕获组00是键名)获取值。

      这里$s 必须是一个字符串。如果您从文本文件中读取,请使用$s = Get-Content file.txt -Raw


      您可以使用变量使其更具动态性:

      $Start = 'values'
      $End = 'values'
      $data = 'data'
      ($s | Select-String -Pattern "(?s)(?<=$Start).*?(?=$End|$)" -AllMatches).Matches.Value |
          Foreach-Object {
              ('N/A',$matches.0)[$_ -match 'data']
          }
      

      【讨论】:

      • 谢谢你帮了我很多,但我还有两个问题。第一个是我之前进行了其他比赛,显然最后一场比赛已经恢复,我在我的列表中找到了它,所以我不知道是否有办法重置它。第二个是当我尝试以这种方式搜索几个“数据”时: Foreach-Object { ('N/A',$matches.0)[$_ -match 'Data1'] ('N/A', $matches.0)[$_ -match 'Data2'] ('N/A',$matches.0)[$_ -match 'Data3'] } “N/A's”总是把自己放在第一位,因此数据不要按正确的顺序出来。
      • 第二个问题只需使用('N/A',$matches.0)[$_ -match 'Data1|Data2|Data3']
      猜你喜欢
      • 2020-06-03
      • 1970-01-01
      • 1970-01-01
      • 2021-08-03
      • 1970-01-01
      • 1970-01-01
      • 2014-12-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多