首页 > 解决方案 > Powershell:如何从文本文件中不符合条件的行中删除 CRLF

问题描述

这看起来很简单,但无法得到我尝试工作的任何东西。我正在尝试从不符合我的标准的行的末尾删除 CRLF,然后将文件输出到新文件。例如本节:

One~Two~Three~Four
Test Plan Pay Work~scheduled payment pending~79f1cf6e~3/8/2020 6:13:07 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM
Test Plan Pay Work~GetCardInfo 
{failed to validate card
}
~f124a822-aa8d-4624-bb8c-ddsfgdfcc21fb~3/8/2020 6:14:31 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM

应该输出如下所示:

One~Two~Three~Four
Test Plan Pay Work~scheduled payment pending~79f1cf6e~3/8/2020 6:13:07 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM
Test Plan Pay Work~GetCardInfo {failed to validate card}~f124a822~3/8/2020 6:14:31 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM

作为一个新手,我尝试过:

Get-Content "C:\temp\errors.csv" | ForEach-Object {
  if ((!$_.EndsWith("AM") -and !$_.EndsWith("PM") -and !$_.EndsWith("Four")))
    {
       $_ -replace ("`r`n",' ')
    }
} | Out-File C:\temp\errors2.csv

但这不起作用。对此有什么想法吗?看起来很简单,但无论我尝试什么都无法让它发挥作用。

标签: powershell

解决方案


Get-Content默认情况下将文本拆分为单独的行并删除换行符。为了防止那个使用参数-Raw。现在您可以使用正则表达式-replace运算符将文本作为一个整体处理:

(Get-Content 'errors.csv' -Raw) -replace '(?<!AM|PM|Four)\r\n', ' ' | 
    Out-File 'errors2.csv'

调用周围的括号Get-Content允许将命令的输出直接用作运算符的左侧操作数-replace(请参阅分组运算符)。

输出:

One~Two~Three~Four
Test Plan Pay Work~scheduled payment pending~79f1cf6e~3/8/2020 6:13:07 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM
Test Plan Pay Work~GetCardInfo  {failed to validate card } ~f124a822-aa8d-4624-bb8c-ddsfgdfcc21fb~3/8/2020 6:14:31 PM
Test Plan Pay Work~Bad Request~680a0bb2~3/8/2020 6:14:00 AM

正则表达式分解:

  • (?<!开始一个否定的lookbehind断言
    • AM|PM|Four任何文字AMPMFour
  • )结束否定的lookbehind断言
  • \r\n换行符

只有在换行符前面没有AM,PM或时,否定的后向断言才使 RegEx 匹配Four。否定的lookbehind 不参与匹配结果,因此只会替换换行符。

正则表达式前瞻、后瞻和原子组

笔记:

这种方法使用将整个文件Get-Content -Raw加载到内存中。如果文件太大,使用 default 的方法,逐行处理输入(可能使用参数在块中)是可行的,但有点复杂。Get-Content-ReadCount


推荐阅读