首页 > 解决方案 > PowerShell5 index[0] 到字符串的第一个实例, index[1] 到第二个实例,依此类推,直到在 6800 行 windows10 批处理文件上完成

问题描述

Powershell5 脚本因 Windows 10 批处理文件中的特殊字符而窒息,还是我的代码根本错误?

解析 6800 行 Windows 10 批处理文件,找到字符串 {LINE2 1-9999} 并将 {1-9999} 替换为代码所在的行号,重新编写批处理文件。{LINE2 1-9999} 有 54 个实例。如果我解析整个批次,则输出前 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 行,其中没有包含字符串?我的代码有什么根本错误吗?

标签: powershellpowershell-5.0

解决方案


只是为了可视化 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]

以及生成的文件内容(上述 bat 的第 2 版)

> 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

推荐阅读