首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从powershell中的shell命令中提取两个关键字之间的多行文本

从powershell中的shell命令中提取两个关键字之间的多行文本
EN

Stack Overflow用户
提问于 2014-11-12 23:47:23
回答 3查看 7.2K关注 0票数 1

我有一个shell命令,我想从Powershell中提取数据。我需要的数据总是位于两个关键字之间,捕获的行数可以改变。

输出可能如下所示。

代码语言:javascript
复制
Sites:
System1: 
RPAs: OK
Volumes: 
  WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX
  WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX
  WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX
Splitters: OK
System2: 
RPAs: OK
Volumes: 
  WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA
Splitters: OK
WAN: OK
System: OK

我想捕获并存储到一个变量(或文本文件,如果更容易?)此数据的一部分将在以后的脚本中重用。例如,我想要捕获System1:和System2:之间的所有内容,这将产生:

代码语言:javascript
复制
RPAs: OK
Volumes: 
  WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_MA
Splitters: OK

我已经尝试过不同的正则表达式组合,但都没有成功。我在这段代码中取得了一定的成功,但它似乎不能处理警告行,我似乎也不能使用Out-File来处理它,只有Write-Host对我帮助不大。

代码语言:javascript
复制
$RP = plink -l User -pw Password 192.168.1.100 "get_system_status summary=no" #extract from

$script = $RP

$in = $false

$script | %{
if ($_.Contains("System1"))
    { $in = $true }
elseif ($_.Contains("System2"))
    { $in = $false; }
elseif ($in)
    { Write-Host $_ }
}

理想情况下,我希望能够使用此脚本并使用它来解析来自任何shell命令的数据。我现在迷失了方向,几乎准备放弃这一点。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-13 00:25:34

一种选择是用换行符连接文本,然后使用带有多行正则表达式的-split:

代码语言:javascript
复制
$text = 
(@'
Sites:
System1: 
RPAs: OK
Volumes: 
  WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX
  WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX
  WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX
Splitters: OK
System2: 
RPAs: OK
Volumes: 
  WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA
  WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA
Splitters: OK
WAN: OK
System: OK
'@).split("`n") |
foreach {$_.trim()} 

$text -join "`n" -split '(?ms)(?=^System\d+:\s*)' -match '^System\d+:'

System1:
RPAs: OK
Volumes:
WARNING: Storage group DR_UCS_01-08 contains both replicated and unreplicated volumes. ; CS_TX
WARNING: Storage group DR_UCS_21-28 contains both replicated and unreplicated volumes. ; CS_TX
WARNING: Storage group DR_UCS_31-38 contains both replicated and unreplicated volumes. ; CS_TX
Splitters: OK

System2:
RPAs: OK
Volumes:
WARNING: Storage group MA_UCS_1 contains both replicated and unreplicated volumes. ; CS_MA
WARNING: Storage group MA_UCS_2 contains both replicated and unreplicated volumes. ; CS_MA
WARNING: Storage group MA_UCS_3 contains both replicated and unreplicated volumes. ; CS_MA
Splitters: OK
WAN: OK
System: OK

Edit:一种更通用的解决方案,只捕获两个特定关键字之间的输出:

代码语言:javascript
复制
$regex = '(?ms)System1:(.+?)System2:'

$text = $text -join "`n"

$OutputText = 
[regex]::Matches($text,$regex) |
 foreach {$_.groups[1].value -split }
票数 0
EN

Stack Overflow用户

发布于 2014-11-13 00:12:04

试试这个正则表达式:

代码语言:javascript
复制
$result = ($text | Select-String 'System1:\s*\r\n((.*\r\n)*)\s*System2:' -AllMatches)
$result.Matches[0].Groups[1].Value

其中$text是您的原始输入。请注意,根据您的输入,您可能需要将行尾从\r\n调整为\n。你也可能有一个以上的匹配,我不确定从你的样本。

正则表达式开始匹配

它是System1,后跟任意数量的空格,然后是换行符。它以文字结束匹配

..。中间的中间,

匹配所有后跟换行符的字符。最外面的中间

说要反复匹配那个模式。最后,对该构造进行分组,

这样所有的匹配线都可以被提取出来作为结果。

票数 0
EN

Stack Overflow用户

发布于 2021-02-28 20:02:12

我试着为自己改编这个脚本,我想做同样的事情,但却捕捉到了和之间的内容(note-file from kobo-reader)。最后让它运行起来,看起来是这样的:

代码语言:javascript
复制
$text = @"
The deaths I see are frequently undignified; the dying very often have not accepted or understood their situation, the truth denied them by well-intentioned relatives and doctors. Their death has been stolen from them.

            
        
        
                It is indeed impossible to imagine our own death; and whenever we attempt to do so, we can perceive that we are in fact still present as 
"@
$regex = '(?ms)(.+?)'

#Test
$OutputText = [regex]::Matches($text,$regex) | 
foreach {$_.groups[1].value }
Write-Host $OutputText

#Output
[regex]::Matches($text,$regex) | 
foreach {$_.groups[1].value } |
Out-File c:\temp\kobo\example_out.txt -Encoding utf8
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26890978

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档