【问题标题】:powershell - remove string containing line breaks and spacespowershell - 删除包含换行符和空格的字符串
【发布时间】:2016-02-26 20:31:17
【问题描述】:

我有一个在 powershell (v2) 中运行的脚本,它从文件中删除字符串。

基本流程是:

(Get-Content $Local_Dir1\$filename1) -replace 'longString', 'shortString' | ` 
Set-Content $cfg_Local_Dir\$filename1

Get-Content $Local_Dir1\$filename1 | `
            Where-Object {$_ -notmatch 'stringToMatch'} | `
            Where-Object {$_ -notmatch 'secondStringToMatch'} | `
            Set-Content $Local_Dir1\$filename

这很好用。但是,我有一个烦人的字符串,我无法摆脱。

它基本上包括:一个换行符和回车,4个空格,然后是一个换行符和回车。在十六进制中是0D 0A 20 20 20 20 0D 0A

我怎样才能删除它?

我试过了:

Where-Object {$_ -notmatch '    '} #4 x spaces

但这删除了该行之后的所有内容(这是在第二行)。

我看了:

Where-Object {$_ -notmatch '$([char]0x0D)'}

(如果它删除了所有的回车,我会扩展它)我在另一篇帖子中看到的,但这没有任何作用。

处理这个问题的正确方法是什么?


补充:2015-11-24 13:49

示例数据:

<?xml version="1.0" encoding="UTF-8"?>

<start_of_data>
        <job>123456</job>
        <name>ABC123</name>
        <start></start> 
</start_of_data> 
<start_of_data>
        <job>789012</job>
        <name>DEF345</name>
        <start></start> 
</start_of_data>

最初第2行有一个字符串,被'stringToMatch'删除,空格在第3行。

【问题讨论】:

  • 不应该是Where-Object {$_ -notmatch "$([char]0x0D)"}加上双引号,来扩展变量吗?
  • 谢谢你,我总是把我的报价弄错 - (我应该学会在遇到问题时自动更改我的报价)。 . .

标签: string powershell replace powershell-2.0


【解决方案1】:

这里有几点值得指出。当您使用 -match/-notmatch 时,您正在使用正则表达式。我们可以将您的字符串和空格问题合并为一个字符串。

Get-Content $Local_Dir1\$filename1 | 
    Where-Object {$_ -notmatch 'stringToMatch|secondStringToMatch|\s{4,}'} | 
    Set-Content $Local_Dir1\$filename

这可以使用交替来匹配由管道分隔的任一元素。这绝不是完美的,因为我们没有可使用的示例数据,但是如果您有包含这两个字符串中的任何一个或至少 4 个连续空格的行,它们将被省略。

通过在 cmets 中交谈并查看示例文件,您只是想省略空白行。使用另一个字符串类或正则表达式可以解决这个问题。这些行的功能不同,但都会忽略只是空白的行。

  • ![string]::IsNullOrWhiteSpace($_)
  • -notmatch ^\s+$

我会选择前者,因为它更直观。

Where-Object {![string]::IsNullOrWhiteSpace($_) -and $_ -notmatch 'stringToMatch|secondStringToMatch'}

就像我在 cmets 中所说,如果您对此要求很挑剔,您可以使用 -notmatch ^\s{4}$ 过滤掉恰好包含 4 个空白字符的行


也像sodawillow 说你应该使用双引号来允许变量扩展。由于您使用的是正则表达式\r,因此也可以正常工作。

Where-Object {$_ -notmatch "$([char]0x0D)"}

但是我不认为您无论如何都会看到该角色以排除它。 Get-Content 将清除它以创建一个字符串数组。这可能取决于编码。

【讨论】:

  • 为合并字符串这一点欢呼。我尝试使用双引号,但没有任何区别,当我在 HEX 编辑器中查看时,我的 (xml) 文件中仍然包含 0x0D 字符。当我运行Get-Content $Local_Dir1\$filename1 时,它显示了文件的内容,并且第二行有一行带空格。 (我也意识到为什么当我使用 \s{4} 时我的所有行都消失了 - 我的大部分行在开头都有 6 个空格!!!)
  • @IGGt 如果是正好 4 个空格,那么您可以使用边界\b\s{4}\b 而不是\s{4,} 应该可以解决这个问题。这样它就不会匹配 6 个空格。有更好更简洁的方法可以做到这一点,但这与我的替代示例保持一致。
  • 干杯,我尝试使用 where-Object {$_ -notmatch '\b\s{4,}\b'},但仍然没有运气,该行仍然存在,当我在 HEX 编辑器中打开文件时,它仍然显示该行的 20 20 20 20 0D 0A
  • @IGGt 嗯。您可以托管包含该行的文件的副本吗?我知道那里可能有敏感数据,所以请把它擦掉。你也可以试试这个,也许$_ -notmatch '^\s{4}$'
  • 你是明星!!已经明白了。我正要开始每次都删除第 2 行 - 这不是最好的方法......
【解决方案2】:

试试 .Net String 类:

Where-Object {-not[string]::IsNullOrEmpty(([string]$_).trim())}

Trim 将删除空格,IsNullOrEmpty 将检查其余部分。

【讨论】:

  • 干杯,但它只是导致一个空白文件 - 也许是因为我意识到我的大部分行都以多个空格开头!)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-16
  • 1970-01-01
  • 2018-02-08
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多