提问人:xeric080 提问时间:10/25/2023 更新时间:10/25/2023 访问量:48
如何根据起始行将文本块拆分为多行记录?
How can I split a block of text into multiline records based on the starting line?
问:
我怎样才能把它拆分成单独的字符串/数组/等,以便我可以分别迭代每个字符串/数组/等?目标是将它们分开,以便我可以分析每条记录并插入到 PSCustomObject 中。
我有以下表示 1 次以上扫描的文本块。每条扫描记录都以“根扫描路径”行开头,以“可疑文件”行结尾。
我能够得到的最接近的是以下行,它有效,但后来我丢失了“根扫描路径”行,因为它是分隔符。
$String -Split "Root Scan Path: C:\\"
也可能有 2 个以上的扫描记录。
Root Scan Path: C:\
Scan ID: 03307ad8-1a59-7d4e-8dfe-28864c9d1bc2
Status: Completed
Initiated from: User
Start Time: Monday, October 23, 2023 9:24:18 PM
End Time: Monday, October 23, 2023 9:34:00 PM
Scanned Files: 38311
Unsupported Files: 229479
Traversed Files: 321202
Total Files: 267790
Suspicious Files: 0
Root Scan Path: C:\
Scan ID: f32a64b0-56f5-664c-bf37-a7b120f759d8
Status: Running
Initiated from: User
Start Time: Tuesday, October 24, 2023 6:20:45 PM
End Time:
Scanned Files: 0
Unsupported Files: 0
Traversed Files: 0
Total Files: 0
Suspicious Files: 0
答:
2赞
Olaf
10/25/2023
#1
我会拆分换行符,并用唯一字符(例如等号)替换冒号的第一个出现,并用于获取正确的 PowerShell 对象。ConvertFrom-StringData
@'
Root Scan Path: C:\
Scan ID: 03307ad8-1a59-7d4e-8dfe-28864c9d1bc2
Status: Completed
Initiated from: User
Start Time: Monday, October 23, 2023 9:24:18 PM
End Time: Monday, October 23, 2023 9:34:00 PM
Scanned Files: 38311
Unsupported Files: 229479
Traversed Files: 321202
Total Files: 267790
Suspicious Files: 0
Root Scan Path: C:\
Scan ID: f32a64b0-56f5-664c-bf37-a7b120f759d8
Status: Running
Initiated from: User
Start Time: Tuesday, October 24, 2023 6:20:45 PM
End Time:
Scanned Files: 0
Unsupported Files: 0
Traversed Files: 0
Total Files: 0
Suspicious Files: 0
'@ -split "\r?\n" |
ForEach-Object {
$_ -replace ':(?=\s|$)',' ='
} | ConvertFrom-StringData -Delimiter '='
输出如下所示:
Name Value
---- -----
Root Scan Path C:
Scan ID 03307ad8-1a59-7d4e-8dfe-28864c9d1bc2
Status Completed
Initiated from User
Start Time Monday, October 23, 2023 9:24:18 PM
End Time Monday, October 23, 2023 9:34:00 PM
Scanned Files 38311
Unsupported Files 229479
Traversed Files 321202
Total Files 267790
Suspicious Files 0
Root Scan Path C:
Scan ID f32a64b0-56f5-664c-bf37-a7b120f759d8
Status Running
Initiated from User
Start Time Tuesday, October 24, 2023 6:20:45 PM
End Time
Scanned Files 0
Unsupported Files 0
Traversed Files 0
Total Files 0
Suspicious Files 0
3赞
Santiago Squarzon
10/25/2023
#2
假设每个块之间没有空行,则以下方法可能有效:
$out = [ordered]@{}
$theInputString -split '\r?\n(?=Root Scan Path:)' | ForEach-Object {
foreach ($line in $_ -split '\r?\n') {
$key, $value = $line.Split(':', 2).Trim()
$out[$key] = $value
}
[pscustomobject] $out
$out.Clear()
}
为了简单起见,我建议 Olaf 使用 ConvertFrom-StringData
,但是该 cmdlet 有一个警告,即它不保留属性的顺序(因为哈希表不确保其键顺序), 我注意到的另一个警告是它使用字符串中的反斜杠 \
(不确定是否记录了):
'Root Scan Path=C:\' | ConvertFrom-StringData
为了澄清上述情况,正如 mklement0 在注释中指出的那样,正在使用的反斜杠是预期的,该字符需要用另一个反斜杠进行转义。另请参阅 GitHub 问题 #20418。
'Root Scan Path=C:\\' | ConvertFrom-StringData
Name Value
---- -----
Root Scan Path C:\
评论
2赞
Olaf
10/25/2023
非常整洁。👍🏼 我实际上错过了实际上有 2 个数据集。🤭🤷🏼♂️
2赞
Santiago Squarzon
10/25/2023
谢谢@Olaf,您的方法也很好用,只需要稍作更改,请参阅此处: i.imgur.com/Vk2zu0n.png // 我不确定这个 cmdlet 消耗 tho 是怎么回事,这很糟糕\
1赞
xeric080
10/25/2023
我从你的两个答案中学到了一些有用的东西,所以谢谢!我将接受这个问题,因为问题的核心是关于将文本块拆分为两组单独的数据集。您的解决方案在第一次拆分中包含它。👍
2赞
Olaf
10/25/2023
@SantiagoSquarzon 当你提到它时,我注意到缺少反斜杠。🤷🏼 ♂️ 这不会打扰我,但你是对的——这很奇怪。无论如何,我认为您的方法更加复杂和强大。👍🏼
2赞
mklement0
10/25/2023
来自 ConvertFrom-StringData
:“cmdlet 可以使用方法将反斜杠 () 解释为字符串数据中的转义字符”。另请参阅:GitHub 问题 #20418,建议通过开关选择退出。\
Regex.Unescape
-Raw
评论