<# .SYNOPSIS Выборка строк с заменой текста по шаблону-поиску, при наличии шаблона-флага, разрешающего изменение файла. .Description Скрипт предназначен для выборки строк и замены текста по шаблону либо во всем файле сразу, либо построчно, в зависимости от наличия переключателя -full Все данные в файле заменяются по результатам выборки. .Parameter Source Обязательный: Указываются файлы или каталоги (в случае каталога, будут выбраны файлы содержащиеся в нем по фильтру) .Parameter Filter Необязательный: Фильтр для отбора файлов. Поддерживаются маски .Parameter Flag Обязательный: Шаблон [regexp] - при найденном совпадении в файле, разрешает его изменение .Parameter Pattern Необязательный: Шаблон [regexp] для поиска подстроки, которую необходимо заменить .Parameter Substitute Необязательный: Строка на которую будет заменена найденная подстрока по шаблону. .Parameter String Необязательный: Номер выводимых строк. Если число единственное, то выводится каждая строка через это число. Например: каждая пятая строка. Если указано более одного числа, то выводятся строки с такими номерами. .Parameter Number Необязательный: Номер вхождения по шаблону подстроки, который будет заменен. Возможно использование строковых значений 'last' и 'first' .Parameter Encoding Необязательный: Строковое значение кодировки, используемое в тексте. По умолчанию: UTF8 .Parameter Full Переключатель: Для обработки сразу всего файла, как единой строки. .Parameter Whatif Переключатель: Для визуальной проверки результатов, они выводятся в консоль. Никаких изменений в файл не вносится. .Example .\script.ps1 -sour 'test.txt','C:\TEST' -filt '*.txt' -flag 'Таня' -patt 'Коля' ` -sub 'Вася' -num 'last' -str 6,15 -full -whatif Это пример выборки для дальнейшей обработки, состоящей из файла test.txt и всех найденных файлов с расширением .txt в каталоге C:\TEST, с указанием флага 'Таня', который в случае найденного совпадения в файле, разрешит его изменение. Для поиска заменяемой подстроки используется шаблон 'Коля', а для замены 'Вася'. Т.к. присутствует переключатель -full, то параметр -String, в данном случае, будет проигнорирован и обработан будет файл целиком, как единая строка. Заменено будет последнее вхождение искомой подстроки во всем файле. Результат выводится в консоль и в файле ничего не изменяется, т.к. используется переключатель -whatif .Example .\script.ps1 -sour 'test.txt' -flag 'Таня' -patt 'Коля' -sub 'Вася' -num 3 -str 6,15 Это пример выборки для дальнейшей обработки, состоящей из файла test.txt, с указанием флага 'Таня', который в случае найденного совпадения в файле, разрешит его изменение. Для поиска заменяемой подстроки используется шаблон 'Коля', а для замены 'Вася'. В данном случае, выводятся строки с номерами 6 и 15, причем в каждой из них будет заменено третье вхождение искомой подстроки. Если в строке отсутствуют совпадения с шаблоном поиска, то строка останется неизменной. Все результаты будут записаны в исходный файл. .Example .\script.ps1 -config 'c:\temp\config.xml' -whatif Это пример выборки для дальнейшей обработки по считанным параметрам из конфигурационного файла. Пример файла конфигурации: <?xml version='1.0' encoding='utf-8'?> <Root> <Part Description="Конфигурационный файл" Enable="1" /> <Configuration> <Source>test.txt</Source> <Source>d:\TEST</Source> <Filter>*.txt</Filter> <Flag>\bТаня\b</Flag> <Pattern>Коля</Pattern> <Substitute>Вася</Substitute> <Strings>2,8,15</Strings> <Number>last</Number> <Encoding>utf8</Encoding> </Configuration> </Root> Результат выводится в консоль и в файле ничего не изменяется, т.к. используется переключатель -whatif .Notes Created By YuS Version: 1.00 Date: 22/04/2019 Purpose/Change: Первая версия Version: 1.01 Date: 23/04/2019 Purpose/Change: Изменен тип параметра Number с обязательный на необязательный, добавлена валидация данных этого параметра. Если требуется только вывод определенных строк, то параметры Pattern,Substitute,Number теперь заполнять необязательно. Поправлены старые баги, добавлены новые. :) Date: 24/04/2019 Purpose/Change: Добавлена возможность использования конфигурационного файла формата XML. Поправлены старые баги, добавлены новые. :) .Link http://forum.ru-board.com/topic.cgi?forum=5&topic=48565&start=2080#15 #> [cmdletbinding(defaultparametersetname="xmlfile")] param ( [parameter(parametersetname="xmlfile")] [string]$configuration = $psscriptroot+"\config.xml", [parameter(mandatory=$true,parametersetname="SourcePath")] [string[]]$source,[string]$filter, [parameter(mandatory=$true,parametersetname="FlagSet")] [string]$flag,[string]$pattern,[string]$substitute,[int[]]$strings,[switch]$full, [validatepattern("\b(first|last|\d+)\b")] [string]$number,[switch]$whatif,[string]$encoding = 'utf8' ) [xml]$xml = gc $configuration -enc utf8 if ($xml -and [int]$xml.root.part.enable -eq 0){'Приехали';exit} $source,$filter = $xml.root.configuration.source,$xml.root.configuration.filter $flag,$pattern = $xml.root.configuration.flag,$xml.root.configuration.pattern $substitute,$number = $xml.root.configuration.substitute,$xml.root.configuration.number $strings = $xml.root.configuration.strings -split " |," filter get-element { $pth = gi $_ -force if(test-path $pth.fullname -patht container){ dir $pth.fullname -filt $filter -file -force } else {$pth} } filter set-replace { if($pattern){ if($c){ $f = $_|sls -patt $pattern -all if ($c -eq 'first'){ [int]$k = 0 } elseif ($c -eq 'last') { [int]$k = $f.matches.length - 1 } else { [int]$k = $c - 1 } if($f.matches.length -gt $k -and $f.matches.length -gt 0){ $tmp,$len = [int]$f.matches[$k].index,[int]$f.matches[$k].length "$_".remove($tmp,$len).insert($tmp,$substitute) } else {$_} } } else {$_} } function get-entrynum ($a,[int[]]$b,$c){ $arr = gc $a -raw -enc $encoding if ($flag -and $arr -match $flag){ if ($full){ $arr|set-replace } else { gc $a -enc $encoding|%{$i=0}{ $i++ if ($b.length -eq 1){ if($b -eq $i){$_|set-replace;$i=0} } elseif ($b.length -gt 1){ if($b -contains $i){$_|set-replace} } } } } } $source|get-element|%{ $file = $_.fullname try { $n = [string[]](get-entrynum $file $strings $number) if($whatif){$n.trim("`n");'==='+$file} else {$n.trim("`n")|sc $file -enc $encoding} }catch{ write-host Ошибка! Не выбрано ни одной строки. $("`n==="+$file) -for red } } |