用于匹配和替换部分匹配模式的 Powershell
Powershell for Matching and Replacing Partially Matching Patterns
整个星期都在发疯无法解决这个问题。我有一个字典单词文件,一次有几百万个单词,现在我们假设它只是一个文本文件 "Words.txt",其中包含:
应用程序
苹果
应用
酒吧
蝙蝠
面糊
帽
首都
糖果
我需要它做的是将每个字符串与文件的其余部分进行匹配,并且只写入第一次命中的输出。这将按字母顺序排列。
例如,上述单词的所需输出为:
应用程序 - 由于模式 "App" 首先被看到并跳过 "Apple" 和“应用程序
条形图 - 由于模式 "Bar",独一无二
Bat - 由于模式 "Bat" 先被看到并跳过 "Batter"
上限 - 由于模式 "Cap" 先被看到并跳过 "Capital"
糖果 - 由于图案 "Candy",独一无二
我完全不知道该怎么做的是如何忽略初始命中后发生的匹配并移动到 'new' 模式。如果其他多余的模式被覆盖或只是跳过就可以了,不管怎样。
我有一个匹配模式的脚本,但我不知道如何得到所需的输出:(有什么帮助吗?!?!
$Words = "C:\Words.txt"
[System.Collections.ArrayList]$WordList = Get-Content $Words
$Words
$Words2 = $Words
$i = 0
$r = 0
Foreach ($item in $Words)
{
foreach ($item2 in $Words2)
{
if ($item2 -like "$item*")
{
write-host $("Match " + [string]$i + " " + $item + " " + [string]$r + " " + $item2)
}
$r++
}
$i++
}
一行一行地处理并将它们与最近的唯一前缀进行比较就足够了:
$prefix = '' # initialize the prefix pattern
foreach ($line in [IO.File]::ReadLines('C:\Words.txt')) {
if ($line -like $prefix) { continue } # same prefix, skip
$line # output new unique prefix
$prefix = "$line*" # save new prefix pattern
}
注意:由于您提到输入文件很大,我使用 System.IO.File.ReadLines
而不是 Get-Content
来读取文件,以获得更好的性能。
注意:您的示例输入路径无论如何都是 完整 路径,但请务必 始终 传递完整路径.NET 方法,因为 .NET 的工作目录通常不同于 PowerShell 的。
如果将 foreach
循环包装在 & { ... }
中,则可以将结果以流方式(逐行,无需先将所有结果收集到内存中)传输到 Set-Content
。
但是,也使用 .NET 类型进行保存会执行得更好 - 请参阅 的底部部分。
整个星期都在发疯无法解决这个问题。我有一个字典单词文件,一次有几百万个单词,现在我们假设它只是一个文本文件 "Words.txt",其中包含:
应用程序 苹果 应用 酒吧 蝙蝠 面糊 帽 首都 糖果
我需要它做的是将每个字符串与文件的其余部分进行匹配,并且只写入第一次命中的输出。这将按字母顺序排列。
例如,上述单词的所需输出为:
应用程序 - 由于模式 "App" 首先被看到并跳过 "Apple" 和“应用程序 条形图 - 由于模式 "Bar",独一无二 Bat - 由于模式 "Bat" 先被看到并跳过 "Batter" 上限 - 由于模式 "Cap" 先被看到并跳过 "Capital" 糖果 - 由于图案 "Candy",独一无二
我完全不知道该怎么做的是如何忽略初始命中后发生的匹配并移动到 'new' 模式。如果其他多余的模式被覆盖或只是跳过就可以了,不管怎样。
我有一个匹配模式的脚本,但我不知道如何得到所需的输出:(有什么帮助吗?!?!
$Words = "C:\Words.txt"
[System.Collections.ArrayList]$WordList = Get-Content $Words
$Words
$Words2 = $Words
$i = 0
$r = 0
Foreach ($item in $Words)
{
foreach ($item2 in $Words2)
{
if ($item2 -like "$item*")
{
write-host $("Match " + [string]$i + " " + $item + " " + [string]$r + " " + $item2)
}
$r++
}
$i++
}
一行一行地处理并将它们与最近的唯一前缀进行比较就足够了:
$prefix = '' # initialize the prefix pattern
foreach ($line in [IO.File]::ReadLines('C:\Words.txt')) {
if ($line -like $prefix) { continue } # same prefix, skip
$line # output new unique prefix
$prefix = "$line*" # save new prefix pattern
}
注意:由于您提到输入文件很大,我使用 System.IO.File.ReadLines
而不是 Get-Content
来读取文件,以获得更好的性能。
注意:您的示例输入路径无论如何都是 完整 路径,但请务必 始终 传递完整路径.NET 方法,因为 .NET 的工作目录通常不同于 PowerShell 的。
如果将 foreach
循环包装在 & { ... }
中,则可以将结果以流方式(逐行,无需先将所有结果收集到内存中)传输到 Set-Content
。
但是,也使用 .NET 类型进行保存会执行得更好 - 请参阅