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