在字符之间拉文本

时间:2013-01-02 15:19:52

标签: powershell

如何在两个单词之间拉文本?我知道正则表达式可以做到这一点,我一直在寻找,但我尝试的代码根本不适用于我...像正则表达式砖一样无能为力......所以可能我做错了...

我有一个文本文件,想要查询这些文本字符串之间显示的内容:

  

[问题设备]

     

设备PNP设备ID错误代码

     

[USB]

我试过这样做,但没有在哪里!

$devices = Get-Content c:\temp\dev.txt | out-string [regex]::match($devices,'(?<=\<Problem Devices\>).+(?=\<USB\>)',"singleline").value.trim()

You cannot call a method on a null-valued expression.
At line:1 char:141
+ $devices = Get-Content c:\temp\dev.txt | out-string [regex]::match($devices,'(?<=\<Problem Devices\>).+(?=\<USB\>)',"
singleline").value.trim <<<< ()
    + CategoryInfo          : InvalidOperation: (trim:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

2 个答案:

答案 0 :(得分:1)

不需要管道到out-string; get-content将文件的每一行作为单独的对象发送到管道中。因此,您希望使用foreach-object迭代这些对象。

$devices = Get-Content c:\temp\dev.txt | foreach-object{[regex]::match($devices,'(?<=\<Problem Devices\>).+(?=\<USB\>)',"singleline").value.trim()}

但是,您仍然遇到尝试trim() null个对象的问题 - 如果您的正则表达式匹配找不到匹配项,则无法调用value.trim()

当您的输入文件有<Problem Devices>时,您的正则表达式尝试匹配[Problem Devices]

不要尝试在一组管道步骤中执行所有操作,而是要解决问题:

  1. 对于文件中的每一行,检查[问题设备]
  2. 对于每个后续行,如果是[USB],则退出循环。如果它不是[USB],则将每一行捕获到变量中(构建这些行的数组)
  3. 在循环之后,迭代刚刚构建的数组的每个元素,以解析每个值(创建PSObjects的集合(每个设备一个),或散列集合(每个设备一个),具体取决于根据你的需要)。

答案 1 :(得分:0)

如果您对正则表达式不满意,还有其他方法:

$ test = $ false

$ devices = get-content file.txt |

foreach {

if ($_.trim() -eq '[Problem Devices]'){$test = $true}

elseif ($_.trim() -eq '[USB]') {$test = $false}

elseif ($test){$_}

} | where {$_.trim()}