【问题标题】:How to read lines between 2 special characters in txt-file with Powershell如何使用 Powershell 读取 txt 文件中 2 个特殊字符之间的行
【发布时间】:2017-12-02 18:34:24
【问题描述】:

您好,我几乎是 Powershell 的新手。 我需要读取文本文件中的一些特定行并将它们放入不同的数组中。 我有一个看起来像这样的文件:

[Servers]
Server1
Server2
Server3
Server4
[IP]
10.10.10.10
10.10.10.20
10.10.30.30
192.168.1.2
192.168.1.4
[Path]
C:\Log\*.log
D:\Files\*.txt
D:\Files\*.csv
D:\Files\*.xml
[Gateway]
10.10.10.1
10.10.30.2
192.168.1.1

我的问题是我需要阅读 [Servers] 中的行(有时 3 行,有时更多)并将它们放入数组中。 不知道行数时如何选择[Servers][IP]之间的所有行?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    密切相关:Grabbing specific sections of a txt file via Powershell

    如果可以先将整个文件读入内存:

    $regex = '(?ms)\A.*?^\[Servers\]\s*\r?\n(.*?)(?:\r?\n\[.*|(?:\r?\n)?\Z)'
    $servers = (Get-Content -Raw file.txt) -replace $regex, '$1' -split '\r?\n'
    

    重构为一个简单的函数,它接受输入文件和感兴趣部分的名称:

    function get-SectionLines([string] $LiteralPath, [string] $SectionName) {
      $regex = '(?ms)\A.*?^\[{0}\]\s*\r?\n(.*?)(?:\r?\n\[.*|(?:\r?\n)?\Z)' -f [regex]::Escape($SectionName)
      (Get-Content -Raw -LiteralPath $LiteralPath) -replace $regex, '$1' -split '\r?\n'
    }
    
    $servers = get-SectionLines file.txt Servers
    

    说明

    • Get-Content -Raw 将整个文件作为单个字符串读入内存。
    • -replace 然后对一个多行字符串进行操作,使用正则表达式(正则表达式)来匹配 整个 输入字符串,并带有 捕获组 ((...))仅匹配感兴趣的行,并仅将整个字符串替换为捕获组,从而有效地仅返回该部分的行。
    • 最后,-split '\r?\n' 将提取的多行字符串拆分为行数组。

    正则表达式的解释

    • 内联正则表达式选项(?sm) 同时打开m多行和s单行选项:

      • m 表示^$ 匹配每个 的开头和结尾,而不是整个输入字符串。
      • s 表示元字符. 也匹配\n 字符,因此.* 等表达式可用于匹配跨行
    • \A 匹配(多行)输入的开头,\Z 匹配结尾。

    • \r?\n 匹配单个换行符,包括 CRLF 和 LF 变体。

    • (.*?) 是捕获组,它(非贪婪地)捕获部分内的所有内容。

    • (?:\r?\n\[.*|(?:\r?\n)?\Z) 使用非捕获组 ((?:...)) 来匹配所有感兴趣部分的内容,这可以是下一个的开始> 部分(换行符后跟[)或输入文件的结尾(有或没有尾随换行符)。

    • 请注意,正则表达式匹配 整个 输入字符串,然后将其替换为仅在第一个(也是唯一的)捕获组中捕获的感兴趣的子字符串(范围) (@987654343 @)。

    【讨论】:

      【解决方案2】:

      方法经典:

      $found=$false
      $Listword=(gc C:\temp\list.txt).Split("[]".ToCharArray())
      
      $Servers=foreach ($item in $Listword)
      {
          if ($item -eq "IP") { break }
      
          if ($item -eq "Servers") {$found=$true; continue}
      
          if ($found) {$item}
      }
      
      $Servers
      

      【讨论】:

        猜你喜欢
        • 2017-10-02
        • 2020-11-18
        • 1970-01-01
        • 2015-01-28
        • 1970-01-01
        • 1970-01-01
        • 2016-02-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多