简体   繁体   English

PowerShell5将index [0]设置为字符串的第一个实例,将index [1]设置为第二个实例,依此类推,直到在6800行Windows10批处理文件中完成

[英]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.

相关问题 PowerShell将index [0]指向字符串的第一个实例,将index [1]指向第二个实例,依此类推直到完成 - PowerShell index[0] to the first instance of the string, index[1] to the second instance and so on till finished 如何通过powershell访问windows10中的mdb文件? - How to access mdb file in windows10 by powershell? Powershell 选择字符串匹配文件中的第一个实例和 output 文件名 - Powershell select-string match first instance in file and output filename PowerShell 字符串中字母的第一个索引 - PowerShell first index of a letter in a string PowerShell中从头到尾的数组索引 - Array index from first to second last in PowerShell 批处理/ Powershell为文件中的每一行替换字符串中的前2个字符 - Batch / Powershell replace first 2 characters from string for each line in file 无法在Windows10上加载Powershell - Powershell cannot be loaded on Windows10 视窗10 | Powershell 重定向到 Microsoft 商店 - Windows10 | Powershell redirecting into Microsoft store 如何删除 Windows PowerShell 中文本文件中每个(相同)行的 1 个实例并将剩余的相同行分组? - How to remove 1 instance of each (identical) line in a text file in Windows PowerShell and group the remaining identical lines? Powershell 替换从新行开始的单词的第一个实例 - Powershell replace first instance of word starting on new line
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM