остановить скрипт, когда цель (найти и заменить текст) достигнута 1 или 2 или 3 раза в зависимости от конфигурации - PullRequest
0 голосов
/ 14 апреля 2020

Что делать, если какой-то файл содержит строки типа

11111111111111
22222222222222
33333333333333
44444444444444
22222222222222
33333333333333
22222222222222
11111111111111

, и мне нужно найти и заменить 22222222222222 на 777777777777777 всего 2 раза при обработке строки файла строкой с помощью foreach и сохранить файл с изменениями после этого.

$file = 'path_to\somefile.txt'
foreach($string in $file) 
{
   $new_string = $string -replace '22222222222222', '777777777777777'
}
$string | Out-file $file

Я понимаю, что приведенный выше скрипт заменит все строки и будет сохранен только с одной строкой вместо моих требований.

1 Ответ

0 голосов
/ 14 апреля 2020

Согласно комментарию, необходимо отслеживать, сколько выполнено замен.

Чтобы прочитать файл построчно, используйте. Net * StreamReader.ReadLine () . Через некоторое время l oop продолжайте чтение, пока не дойдете до конца файла.

При чтении строк есть несколько вещей. Отслеживайте, сколько раз встречается заменяемая строка, и при необходимости заменяйте ее. Результаты должны быть сохранены в обоих случаях: строка, которая была заменена, и все остальные строки тоже.

Медленно добавлять содержимое в файл построчно, даже в дни твердотельных накопителей. Массовая операция намного эффективнее. Сохраните измененные данные в StringBuilder. После обработки всего файла запишите содержимое одной операции. Если размер файла будет большим (один гигабайт или более), рассмотрите возможность записи 10 000 строк за раз. Вот так

$sb = New-Object Text.StringBuilder
$reader = [IO.File]::OpenText("MyFile.csv")
$found = 0
$oldVal = '22222222222222'
$newVal = '777777777777777'

# Read the file line by line
while($null -ne ($line = $reader.ReadLine())) {

    # Only change two first occurrances
    if( ($found -lt 2) -and ($line -eq $oldVal) ) {
        ++$found
        $line = $newVal
    }

    # Add data into a buffer
    [void]$sb.AppendLine($line)
}

add-content "SomeOtherFile.csv" $sb.ToString()
$reader.close()
...