PowerShell5指数[0]到字符串的第一个实例,索引[1]到第二实例等等,直到完成了一个680

2019-10-28 10:08发布

Powershell5脚本特殊字符窒息在Windows 10批处理文件或者是我的代码基本上是错误的?

解析6800行的Windows 10批处理文件中,找到字符串{LINE2 1-9999}和{替换1-9999}与行号的代码是,重新编写批处理文件。 有54个实例{LINE2 1-9999}。 如果我解析整个批次中的第54行被outputed,其中没有一个包含字符串。

$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线,其中没有包含字符串? 是不是有什么根本性的错误我的代码?

Answer 1:

你的脚本将只解析包含“LINE2 NNNN”令牌您输入脚本的行数。 所以在上面你的第二个输入例如,从9线输入的,只有7个含有“LINE2 NNNN”,所以你只得到第7行处理。 原因是这样的:

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

此行包含所有包含匹配的文本行的数组,所以$lines是7点的整数数组。 后来在你的循环,你只迭代,许多项目:

$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"


Answer 2:

只是为了形象化什么选择字符串返回以及如何替换基于索引文件内容的行号(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)

> 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


文章来源: PowerShell5 index[0] to the first instance of the string, index[1] to the second instance and so on till finished on a 6800 line windows10 batch file