Индекс PowerShell5 [0] для первого экземпляра строки, индекс [1] для второго экземпляра и т. Д. До конца для пакетного файла windows10 с 6800 строками - PullRequest
0 голосов
/ 15 февраля 2019

Сценарий Powershell5 перекрывает специальные символы в пакетном файле Windows 10 или мой код в корне неверен?

Разбор 6800 строки пакетного файла Windows 10, поиск строки {LINE2 1-9999} и замена {1-9999} с номером строки, на которой включен код, переписать пакетный файл.Есть 54 экземпляра {LINE2 1-9999}.Если я анализирую весь пакет, первые 54 строки выводятся, ни одна из которых не содержит строку.

$lines = sls "LINE2" $env:windir\_61.bat | Select-Object -ExpandProperty LineNumber
gc $env:windir\_61.bat -OutVariable Content
$output = for ($index = 0; $index -lt $lines.count; $index++) {
$Content[$index] -replace "LINE2.*", "LINE2 $($lines[$index])"
} 
$output | sc "$env:TEMP\somebadhat.bat"

Если _61.bat равен:

TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1243 
TITLE %TIME%   DOC/SET YQJ8   LINE2 1887 
SET ztitle=%TIME%: WINFOLD   LINE2 2557 
TITLE %TIME%   _*.* IN WINFOLD   LINE2 2597 
TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 3672 
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4922 

Результаты:

TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1
TITLE %TIME%   DOC/SET YQJ8   LINE2 2
SET ztitle=%TIME%: WINFOLD   LINE2 3
TITLE %TIME%   _*.* IN WINFOLD   LINE2 4
TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 5
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 6 

Если _61.bat равен:

TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1243
TITLE %TIME%   DOC/SET YQJ8   LINE2 1887
SET ztitle=%TIME%: WINFOLD   LINE2 2557
TITLE %TIME%   _*.* IN WINFOLD   LINE2 2597
TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 3672
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4922
:: Microsoft Windows [Version 10.0.17134.345] 64-BIT
@ECHO OFF 
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4923

Результаты:

TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1
TITLE %TIME%   DOC/SET YQJ8   LINE2 2
SET ztitle=%TIME%: WINFOLD   LINE2 3
TITLE %TIME%   _*.* IN WINFOLD   LINE2 4
TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 5
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 6
:: Microsoft Windows [Version 10.0.17134.345] 64-BIT
@ECHO OFF

TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4923

отсутствует.

Существует 30 экземпляровиз @.Например:

SET p= & title NetFix v1.0a by Giovanni Heward (g@utahjrs.com) complete!
%PROGRAMFILES%\7-Zip\7z.exe" u -t7z -x@"%WINDIR%\_exclude7z.txt"

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

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Просто чтобы визуализировать, что возвращает Select-String и как заменить номер белья в содержимом файла на основе индекса (подход zdan гораздо более эффективен)

## Q:\Test\2019\02\15\SO_54712715.ps1
$FilePath = '.\_61v2.bat'
$FileContent = Get-Content $FilePath
$FileMatches = Select-String -Path $FilePath -Pattern '(?<=LINE2 )\d+\s?$'

ForEach ($FM in $FileMatches){
   "{0}:{1} [{2}=>{0}]" -f $FM.LineNumber,$FM.Line,$FM.Matches.Value
   $FileContent[$FM.LineNumber-1] = $FM.Line.Replace($FM.Matches.Value,$FM.LineNumber)
}
$FileContent | Set-Content $FilePath

Пример вывода:

> Q:\Test\2019\02\15\SO_54712715.ps1
1:TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1243 [1243=>1]
2:TITLE %TIME%   DOC/SET YQJ8   LINE2 1887 [1887=>2]
3:SET ztitle=%TIME%: WINFOLD   LINE2 2557 [2557=>3]
4:TITLE %TIME%   _*.* IN WINFOLD   LINE2 2597 [2597=>4]
5:TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 3672 [3672=>5]
6:TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4922 [4922=>6]
9:TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 4923 [4923=>9]

и итоговое содержимое файла (версия 2 вышеупомянутого bat)

> gc .\_61v2.bat
TITLE %TIME%   NO "%zmyapps1%\*.*" ARCHIVE ATTRIBUTE   LINE2 1
TITLE %TIME%   DOC/SET YQJ8   LINE2 2
SET ztitle=%TIME%: WINFOLD   LINE2 3
TITLE %TIME%   _*.* IN WINFOLD   LINE2 4
TITLE %TIME%   %%ZDATE1%% YQJ25   LINE2 5
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 6
:: Microsoft Windows [Version 10.0.17134.345] 64-BIT
@ECHO OFF
TITLE %TIME%   FINISHED. PRESS ANY KEY TO SHUTDOWN ... LINE2 9
0 голосов
/ 15 февраля 2019

Ваш скрипт будет анализировать только количество строк вашего входного скрипта, которые содержат токен "LINE2 nnnn".Итак, во втором примере ввода, указанном выше, из 9 строк ввода только 7 содержат «LINE2 nnnn», поэтому вы обрабатываете только первые 7 строк.Причина в следующем:

$lines = sls "LINE2" c:\temp\_61.bat | Select-Object -ExpandProperty LineNumber

Эта строка содержит массив всех строк, содержащих соответствующий текст, поэтому $lines - это массив из 7 целых чисел.Далее в цикле for вы выполняете итерации только по стольким элементам:

$output = for ($index = 0; $index -lt $lines.count; $index++) {

Вам не нужен массив $lines, просто используйте индекс цикла по содержимому, чтобы определить номер строки:

gc $env:windir\_61.bat -OutVariable Content 
$output = for ($index = 0; $index -lt $Content.count; $index++) {
$Content[$index] -replace "LINE2.*", "LINE2 $($index)"
} 
$output | sc "$env:TEMP\somebadhat.bat"

Обратите внимание, вы можете немного очистить ваш скрипт, удалив временные переменные, протолкнув все данные по конвейеру:

gc $env:windir\_61.bat | foreach -begin {$lc = 1} -process {
    $_ -replace "LINE2 \d*", "LINE2 $lc";
    $lc += 1
} | out-file "$env:TEMP\somebadhat.bat"
...