如何使用Powershell读取txt文件中2个特殊字符之间的行

时间:2017-12-02 18:34:24

标签: powershell

嗨,我几乎是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]之间的所有行?

2 个答案:

答案 0 :(得分:0)

密切相关: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)使用非捕获组((?:...))来匹配感兴趣的部分之后的所有,这可以是的开头下一个部分(换行符后跟一个[)或输入文件的结尾(带或不带尾随换行符)。

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

答案 1 :(得分:0)

经典方法:

$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