Как написать bat-скрипт, который удалит все строки, содержащие определенные значения, используя многопоточность?

Как многопоточно удалить строки из большого списка, используя другой список в качестве фильтра, чтобы ускорить скрипт bat, который сейчас работает медленно?
  • 19 января 2024 г. 15:39
Ответы на вопрос 2
Для создания многопоточного bat-скрипта (batch file) на самом деле bat-скрипты не предназначены. Они работают только в однопоточном режиме. Многопоточность в привычном понимании невозможно реализовать с использованием только средств командной строки Windows. Вместо этого можно запускать несколько параллельных процессов, но управлять ими и их взаимодействием будет сложно.

Однако если вам нужно обработать большие файлы и удалить строки, содержащие определенные значения, можно попробовать использовать другие средства, например PowerShell или Python скрипт, которые лучше подходят для многопоточности и обработки текстов.

Пример решения с использованием PowerShell:

```powershell
# Задаем исходный файл и файл с фильтрами
$inputFile = "C:\path\to\your\inputfile.txt"
$outputFile = "C:\path\to\your\outputfile.txt"
$filterFile = "C:\path\to\your\filterfile.txt"

# Считываем фильтры в массив
$filters = Get-Content $filterFile

# Обрабатываем строки исходного файла
Get-Content $inputFile | Where-Object {
  $line = $_
  $includeLine = $true
  foreach ($filter in $filters) {
    if ($line -like "*$filter*") {
      $includeLine = $false
      break
    }
  }
  return $includeLine
} | Set-Content $outputFile
```

Этот скрипт не является многопоточным, но он должен работать быстрее чем эквивалентный bat-скрипт, особенно с большими файлами. Кроме того, PowerShell поддерживает многопоточность через Jobs или Runspaces, что позволяет создать действительно многопоточный скрипт.

Для использования многопоточности в PowerShell можно поработать с модулем `ForEach-Object -Parallel` (требуется PowerShell 7.0 и выше):

```powershell
# PowerShell 7+ требуется для параметра -Parallel
# Устанавливаем количество параллельных потоков
$maxThreads = [Environment]::ProcessorCount

Get-Content $inputFile | ForEach-Object -Parallel ($filters, $maxThreads) {
    $line = $_
    foreach ($filter in $using:filters) {
        # Если строка соответствует какому-либо фильтру, пропустим её
        if ($line -like "*$filter*") {
            return
        }
    }
    # Вернем строку, если она не была пропущена
    $line
} -ThrottleLimit $maxThreads | Set-Content $outputFile
```

В случае, если вы все же хотите попытаться параллельно обработать данные с использованием bat-скриптов, вам понадобится запустить несколько процессов, каждый из которых будет обрабатывать часть файла. Но это достаточно сложно и не рекомендуется из-за ограничений и сложности управления ошибками и синхронизацией.
бат не лучший выбор для таких вещей, работает ужасно медленно и оптимизировать не выйдет. 
Переходите на что-то другое. bash (точнее awk/grep/gnu tools), powershell или накидать скрипт на perl/python
Похожие вопросы