Powershell для сопоставления и замены частично совпадающих шаблонов - PullRequest
1 голос
/ 19 апреля 2020

Безумно всю неделю не мог решить эту проблему. У меня есть файл словарных слов, который будет состоять из нескольких миллионов слов в одном месте, а теперь давайте предположим, что это просто текстовый файл "Words.txt", который имеет:

App
Apple
Application
Bar
Bat
Batter
Cap
Capital
Candy

Что мне нужно сделать, это сопоставлять каждую строку с остальной частью файла и записывать только выходные данные первого попадания. Это будет в алфавитном порядке.

Пример желаемого вывода из слов выше будет:

App - due to pattern "App" being seen first and skips "Apple" and "Application
Bar - due to pattern "Bar", unique
Bat - due to pattern "Bat" being seen first and skips "Batter"
Cap - due to pattern "Cap" being seen first and skips "Capital"
Candy - due to pattern "Candy", unique

Что я абсолютно не могу понять, как это сделать, как игнорировать совпадения, которые происходят после первоначального нажмите и перейдите к «новому» шаблону. Было бы хорошо, если бы другие избыточные шаблоны были перезаписаны или просто пропущены, не имеет значения, как.

У меня есть сценарий для сопоставления шаблонов, но я не знаю, как получить желаемый результат :( Любая помощь?!? !


$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++
} 

1 Ответ

1 голос
/ 19 апреля 2020

Достаточно обработать строки одну за другой и сравнить их с последним уникальным префиксом:

$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 l oop в & { ... } вы можете направить результат в потоковом режиме (построчно, без сбора всех результатов в памяти) до Set-Content.

Однако, используя. * Тип 1031 * для сохранения также будет работать намного лучше - см. Нижнюю часть этот ответ .

...