Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Задать соответствие точному количеству и регистру символов. (http://forum.oszone.net/showthread.php?t=343473)

temphard 29-12-2019 15:56 2902748

Задать соответствие точному количеству и регистру символов.
 
Здравствуйте. Для замены целой/части строки я использую данный скрипт:
Скрытый текст
Код:

$samples = Import-Csv '1.txt' -Encoding UTF8 -Delimiter ' ' -Header 'P1','P2' | select @{N='P1';E = {[regex]::Escape($_.P1)}},P2
$InFile = '2.txt'
$OutFile = 'out.txt'
 
# $JobCount = (gwmi win32_processor | measure NumberOfCores -S).Sum
 
$JobCount = 4 # количество одновременно выполняющихся скрипт-блоков $Job_ReplaceText
$TextBlockSize = 10000 # по сколько строк считывать для параллельной обработки в каждом скрипт-блоке $Job_ReplaceText
 
$Job_ReplaceText =
{
    foreach($sample in $args[1])
    {
        $args[0] = $args[0] -replace $sample.P1,$sample.P2
    }
    Return $args[0]
}
 
$n = 1
$null | Set-Content $OutFile
 
foreach ($block in Get-Content $InFile -ReadCount $TextBlockSize -Encoding UTF8)
{
    Start-Job -Name "Replace-$(($n++))" -ArgumentList $block,$samples -ScriptBlock $Job_ReplaceText
 
    if ($n -gt $JobCount)
    {
        $n = 1
        Get-Job Replace-* | Wait-Job | sort Name | Receive-Job | Add-Content $OutFile -Encoding UTF8
        Get-Job Replace-* | Remove-Job
    }
}
 
Get-Job Replace-* | Wait-Job | sort Name | Receive-Job | Add-Content $OutFile -Encoding UTF8
Get-Job Replace-* | Remove-Job


Проблема в том, что скрипт не чувствителен к регистру и точности строки/части, которую необходимо заменить.
Например в файле 1.txt подготовлены строки для замены (вначале стоит то, что искать а через пробел то, чем это заменить):
Скрытый текст
textstroka1 newstroka1text
textstroka2 newstroka2text
textstroka3 newstroka3text
textstroka4 newstroka4text
textstroka5 newstroka5text
textstroka6 newstroka6text
textstroka7 newstroka7text
textstroka8 newstroka8text
textstroka9 newstroka9text
textstroka10 newstroka000text
textstroka11 newstroka0000text

В файле 2.txt содержится текст:
Скрытый текст
textstroka1
textStroka2
textsTroka3
textstRoka4
textstrOka5
textstroka6
textstroka7
textstroka8
textstroka9
textstroka10
textstroka11

Результат работы скрипта получается такой, то есть строки 2,3,4 и 5 не должны быть изменены, так как регистр некоторых букв не соответствует, поисковому запросу. Кроме того строки 10 и 11 заменены некорректно, потому что не учтены все символы при поиске:
Скрытый текст
newstroka1text
newstroka2text
newstroka3text
newstroka4text
newstroka5text
newstroka6text
newstroka7text
newstroka8text
newstroka9text
newstroka1text0
newstroka1text1

Задача состоит в том, чтобы скрипт выдавал следующее:
Скрытый текст
newstroka1
textStroka2
textsTroka3
textstRoka4
textstrOka5
newstroka6
newstroka7
newstroka8
newstroka9
newstroka000text
newstroka0000text

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

Busla 29-12-2019 20:40 2902795

используйте метод replace вместо оператора -replace

DJ Mogarych 29-12-2019 23:26 2902803

Код:

$samples = Import-Csv 'C:\temp\3\1.txt' -Encoding UTF8 -Delimiter ' ' -Header 'P1','P2'
$InFile = gc 'C:\temp\3\2.txt'
 
$OutFile = foreach ($string in $infile) {
    if ($string -cin $samples.p1) {
    ($samples |? p1 -ceq $string).p2
    }
    else {$string}
}

$OutFile |Out-File 'C:\temp\3\out.txt' -Encoding UTF8


temphard 30-12-2019 01:25 2902824

Цитата:

Цитата Busla
используйте метод replace вместо оператора -replace »

Вы хотели сказать: оператор -replace заменить на -creplace
Спасибо. С регистром все наладилось, а проблема с почти одинаковыми строками осталась.

YuS_2 30-12-2019 08:05 2902845

Цитата:

Цитата DJ Mogarych
if ($string -cin $samples.p1) {
($samples |? p1 -ceq $string).p2
} »

- это не подойдет для случая:
Цитата:

Цитата temphard
Для замены ...части строки »


Цитата:

Цитата temphard
Задача состоит в том, чтобы скрипт выдавал следующее »

по-моему, судя по условию, в Вашем результате ошибка...
Попробуйте:
Код:

$frep = 'd:\test\1.txt'
$fin = 'd:\test\2.txt'
$fout = 'd:\test\out.txt'
[array]$arr = import-csv $frep -enc utf8 -del ' ' -h 'p1','p2'

gc $fin -enc utf8|%{
        $tmp = $_
        for ($i=0;$i -lt $arr.length;$i++){
                if($tmp -cmatch "\b$($arr[$i].p1)\b"){
                        $tmp = $tmp -creplace $arr[$i].p1,$arr[$i].p2
                }
        }
        $tmp
} #|sc $fout -enc utf8

- если вывод в консоль правильный, то удалите символ комментария в последней строке и вывод будет перенаправлен в файл.

Busla 30-12-2019 11:19 2902864

Цитата:

Цитата temphard
Цитата Busla:
используйте метод replace вместо оператора -replace »
Вы хотели сказать: оператор -replace заменить на -creplace »

Я сказал ровно то, что хотел сказать. Операторы -replace и -creplace работают с регулярными выражениями.
Простая замена строк реализована в методе:
Код:

'AaBcCc'.replace('a','z')

YuS_2 30-12-2019 13:34 2902871

Цитата:

Цитата Busla
работают с регулярными выражениями »

по той же причине:
Цитата:

Цитата temphard
Для замены ...части строки »

без регулярок, обойтись будет трудно...

Пример текста, для замены части строки - 9 строка
textstroka1
textStroka2
textsTroka3
textstRoka4
textstrOka5
textstroka6
textstroka7
textstroka8
textstroka9 textstroka11
textstroka10
textstroka11

temphard 31-12-2019 00:37 2902955

Цитата:

Цитата YuS_2
без регулярок, обойтись будет трудно »

Согласен. Поэтому в дальнейшем решил избегать одинаковых строк textstroka1 textstroka11.
Просто использую цифры от 1 до 9 а дальше буквы алфавита:
Скрытый текст
textstroka1
textstroka2
textstroka3
textstroka4
textstroka5
textstroka6
textstroka7
textstroka8
textstroka9
textstrokaА
и т.д.

В итоге код с задачей справляется.
Всем спасибо за помощь и участие.


Время: 00:12.

Время: 00:12.
© OSzone.net 2001-