我们有一个很大(~100MB)的文本文件。 我们需要删除包含某些短语的所有行。我想使用 PowerShell 来替换当前的方法,该方法使用 windows grep 并且是一个 .bat 文件。
问题是,大约有 95 个关键短语。任何包含这些短语的行都必须删除。
关键短语列表包含在“badPhrases.txt”
中,像常规文本文件一样以行分隔。它们大约有 100 个,我不想将它们包含在硬编码列表中,但如果有必要的话我会这样做。
我尝试过几次/几次比较,但我的输出总是比原始输入文件大!或者,0k(空)。我究竟做错了什么?我怀疑问题出在 Where-Object
过滤器中,但我可能是错的。
[string[]]$arrayFromFile = Get-Content -Path '.\badPhrases.txt'
get-content ".\inputfile.txt" | Where-Object {$_ -notlike $arrayFromFile} | Out-File ".\clean_data.txt" -Force
我尝试过 -notlike、-notin -notmatch 和 -notcontains (同时以看似合乎逻辑的方式翻转数组和输入对象)。比如...
Where-Object {$arrayFromFile -notin $_}
....
Where-Object {$_ -notcontains $arrayFromFile}
....
Where-Object {$_ -notlike arrayFromFile}
我已经搜索了 stackOverflow 并进行了谷歌搜索,但我找不到任何未失效的链接,可以解决这个确切的用例。有一个“嘿脚本人员”引用,但是......链接已失效。
最佳答案
使用 Select-String
,它通过传递给其
-Pattern
的字符串数组支持多个搜索条件参数:
Select-String -NotMatch -SimpleMatch -Pattern (Get-Content -Path .\badPhrases.txt) .\inputfile.txt |
Select-Object -ExpandProperty Line |
Out-File .\clean_data.txt -Force
字符编码警告:在 Windows PowerShell 中,Out-File
默认创建“Unicode”(UTF-16LE) 文件,其中每个字符由(至少)2 字节表示;在PowerShell [Core] 6+中,默认是更明智的无BOM UTF-8;使用-Encoding
参数来显式控制字符编码。
-NotMatch
否定匹配,以便仅输出不匹配任何模式字符串的行。-SimpleMatch
确保模式与输入文件的行相匹配;默认情况下,它们被解释为正则表达式。请注意,默认情况下匹配不区分大小写;使用
-CaseSensitive
,如果需要的话。自
Select-String
输出Microsoft.PowerShell.Commands.MatchInfo
默认情况下的实例Select-Object -ExpandProperty Line
需要提取行本身。- 注意:在 PowerShell 7+ 中,您可以使用
Select-String
的-Raw
改为切换。
- 注意:在 PowerShell 7+ 中,您可以使用
至于你尝试过的:
$_ -notlike $arrayFromFile
您不能使用数组作为字符串比较运算符的RHS,例如 -like
, -match
, -eq
- 您一次只能匹配一个个字符串。
(除此之外,-like
/-notlike
默认匹配整个 LHS;要匹配 LHS 的子字符串,您必须将 *
放在 RHS 的任意一端。)
参见this answer了解更多信息。
$arrayFromFile -notin $_
$_ -notcontains $arrayFromFile
原则上,您必须反转 containment operators -in
and -contains
的操作数及其否定 - 语法为 <array> -contains <value>
和<value> -in <array>
- 但问题是,无论哪种方式都会执行整个字符串的匹配,因此这种方法仅在 $arrayFromFile
时才有效。输入中存在的整行( -in
和 -contains
隐式执行每个元素 -eq
比较)。
关于arrays - Powershell 从包含大量字符串的大文本文件中删除任何行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59650413/