[英]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
Powershell5 script choking on special characters in a Windows 10 batch file or is my code fundamentally wrong? Powershell5脚本使Windows 10批处理文件中的特殊字符阻塞,还是我的代码从根本上错了?
Parse 6800 line Windows 10 batch file, find string {LINE2 1-9999} and replace {1-9999} with the line number the code is on, re-write the batch file. 解析6800行Windows 10批处理文件,找到字符串{LINE2 1-9999},并将{1-9999}替换为代码所在的行号,重新编写批处理文件。 There are 54 instances of {LINE2 1-9999}.
{LINE2 1-9999}有54个实例。 If I parse the entire batch the first 54 lines are outputed, none of which contains the string.
如果我分析整个批处理,则输出前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"
If _61.bat is: 如果_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
Results: 结果:
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
If _61.bat is: 如果_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
Results: 结果:
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
is missing. 不见了。
There are 30 instances of @. @有30个实例。 For example:
例如:
SET p= & title NetFix v1.0a by Giovanni Heward (g@utahjrs.com) complete!
%PROGRAMFILES%\7-Zip\7z.exe" u -t7z -x@"%WINDIR%\_exclude7z.txt"
Is that causing the problem? 那是问题所在吗? What would I replace it with?
我用什么代替它? Why, if i parse the entire file, that has 54 instances of the string, would it output 54 lines, none of which contains the string?
为什么,如果我解析整个文件,该文件具有该字符串的54个实例,它将输出54行,而其中的任何一行都不包含该字符串? Is there something fundamentally wrong with my code?
我的代码有根本上的错误吗?
You're script will only parse the number of lines of your input script that contain the "LINE2 nnnn" token. 您的脚本只会解析输入脚本中包含“ LINE2 nnnn”标记的行数。 So in your second input example above, out of the 9 lines of input, only 7 contain "LINE2 nnnn", so you only get the first 7 lines processed.
因此,在上面的第二个输入示例中,在9行输入中,只有7行包含“ LINE2 nnnn”,因此仅处理了前7行。 The reason is this:
原因是这样的:
$lines = sls "LINE2" c:\temp\_61.bat | Select-Object -ExpandProperty LineNumber
This line contains an array of all the lines that contain the matching text, so $lines
is an array of 7 integers. 该行包含所有包含匹配文本的
$lines
的数组,因此$lines
是7个整数的数组。 Later in your for loop, you are only iterating over that many items: 在后面的for循环中,您仅迭代了许多项:
$output = for ($index = 0; $index -lt $lines.count; $index++) {
You don't really need the $lines
array, just use the loop index over the content to determine the line number: 您实际上并不需要
$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"
Note, you can clean up your script a bit by removing the temporary variables, by pushing all the data through the pipeline: 请注意,您可以通过删除临时变量,通过管道推送所有数据来稍微清理一下脚本:
gc $env:windir\_61.bat | foreach -begin {$lc = 1} -process {
$_ -replace "LINE2 \d*", "LINE2 $lc";
$lc += 1
} | out-file "$env:TEMP\somebadhat.bat"
Just to visualize what Select-String returns and how to replace the linenumber in the index based file content (zdan's approach is much more efficient) 只是为了可视化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
Sample output: 样本输出:
> 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]
and resulting file content (version 2 of above bat) 和生成的文件内容(上述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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.