我知道一些编程基础知识,但这个项目远远超出了我的知识范围。任何帮助都将是非常感激的,提前谢谢你。
有两个带有文本的文件(见下文),我需要检查第一个文件(regex)并使用预定义的模式数组替换另一个文件中的文本。下面是代码和文本文件的示例,这样我就更容易理解我需要什么。
$file = "C:powershellchangescriptAdd.bat"
文件Add.bat:
@Echo Off
cd %systemroot%system32
Reg.exe add "HKCUSoftwareHPHPTwain" /v "DesktopShortcut" /t REG_SZ /d "Yes" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "ModelName" /t REG_SZ /d "tochange" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "HostName" /t REG_SZ /d "tochange" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "IP Address" /t REG_SZ /d "tochange" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "SerialNo" /t REG_SZ /d "tochange" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Services" /t REG_SZ /d "PclPrint eSCL LEDM" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "NetworkType" /t REG_SZ /d "Ethernet" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "MAC" /t REG_SZ /d "tochange" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Manufacturer" /t REG_SZ /d "Hewlett-Packard" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "GUID" /t REG_SZ /d "tochange" /f
xcopy "C:applicationsTwainConfig*" "%USERPROFILE%AppDataLocal" /s /i /Y
Cls
Exit
$filemin = "C:powershellchangescriptpc.txt"
pc.txt文件的内容:
ModelName : HP Color LaserJet Pro M478fxxx
HostName : EPxxxxxx
IP Address : 192.x.x.x
SerialNo : CNBxx3P8WY
Services : PclPrint RestScan eSCL LEDM Fax
MAC : c4651645xxb95
GUID : urn:uuid:8866a4ce-2da1-5b24-6af5-13e5dc7f63b5
这是不工作,但描述我需要的(至少我认为它描述…)
$filemin = "C:powershellchangescriptpc.txt"
$findThisAndReplace = @(
$paternchange1 = '"ModelName" /t REG_SZ /d "tochange" /f"',
$paternchange2 = '"HostName" /t REG_SZ /d "tochange" /f"',
$paternchange3 = '"IP Address" /t REG_SZ /d "tochange" /f"',
$paternchange4 = '"SerialNo" /t REG_SZ /d "tochange" /f"',
$paternchange5 = '"MAC" /t REG_SZ /d "tochange" /f"',
$paternchange6 = '"GUID" /t REG_SZ /d "tochange" /f"'
)
$file = "C:powershellchangescriptAddScan.bat"
$replaceWith = @(
$paternget1 = '"ModelName : *',
$paternget2 = '"HostName : *',
$paternget3 = '"IP Address : *',
$paternget4 = '"SerialNo : *',
$paternget5 = '"MAC : *',
$paternget6 = '"GUID : *'
)
function getsetcontent ($patern, $filemin, $file){
$i=0;
while $1 !> 7
do
(get-content $file) | ForEach-Object {$i++;$_ -Replace $patternchange$i, "$paternget$i"} | Set-Content -Encoding UTF8 $filemin}
合并后的结果应该是:
@Echo Off
cd %systemroot%system32
Reg.exe add "HKCUSoftwareHPHPTwain" /v "DesktopShortcut" /t REG_SZ /d "Yes" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "ModelName" /t REG_SZ /d "HP Color LaserJet Pro M478fxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "HostName" /t REG_SZ /d "EPxxxxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "IP Address" /t REG_SZ /d "192.x.x.x" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "SerialNo" /t REG_SZ /d "CNBxx3P8WY" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Services" /t REG_SZ /d "PclPrint eSCL LEDM" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "NetworkType" /t REG_SZ /d "Ethernet" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "MAC" /t REG_SZ /d "c4651645xxb95" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Manufacturer" /t REG_SZ /d "Hewlett-Packard" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "GUID" /t REG_SZ /d "urn:uuid:8866a4ce-2da1-5b24-6af5-13e5dc7f63b5" /f
xcopy "C:applicationsTwainConfig*" "%USERPROFILE%AppDataLocal" /s /i /Y
Cls
Exit
你可以用下面的代码来解决这个问题:
((Get-Content pc.txt) -replace '^([^:]+):', '$1=' | Out-String | ConvertFrom-StringData).GetEnumerator() | ForEach-Object -Process { New-Variable -Name $_.key -Value $_.Value -Force }
$ExecutionContext.InvokeCommand.ExpandString(((Get-Content Add.bat) -replace '("([^"]+)"[^"]+)"tochange"', '$1"${$2}"' | Out-String)) | Set-Content AddNew.bat -PassThru
结果:
@Echo Off
cd %systemroot%system32
Reg.exe add "HKCUSoftwareHPHPTwain" /v "DesktopShortcut" /t REG_SZ /d "Yes" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "ModelName" /t REG_SZ /d "HP Color LaserJet Pro M478fxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "HostName" /t REG_SZ /d "EPxxxxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "IP Address" /t REG_SZ /d "192.x.x.x" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "SerialNo" /t REG_SZ /d "CNBxx3P8WY" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Services" /t REG_SZ /d "PclPrint RestScan eSCL LEDM Fax" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "NetworkType" /t REG_SZ /d "Ethernet" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "MAC" /t REG_SZ /d "c4651645xxb95" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Manufacturer" /t REG_SZ /d "Hewlett-Packard" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "GUID" /t REG_SZ /d "urn:uuid:8866a4ce-2da1-5b24-6af5-13e5dc7f63b5" /f
xcopy "C:applicationsTwainConfig*" "%USERPROFILE%AppDataLocal" /s /i /Y
Cls
Exit
regex101 forpc.txt
文件。
regex101 forAdd.bat
文件。
这样做的一种方法是读取pc.txt
与注册值名称和替换字符串,并将其转换为易于使用的哈希表。
然后逐行遍历.bat文件并进行更改:
# organize the values from 'pc.txt' into a Hashtable
# read the file as single multiline string and replace the first colon (:)
# of every line into an equals sign (=).
# then use ConvertFrom-StringData to obtain a Hashtable
$pcHash = (Get-Content -Path 'D:Testpc.txt' -Raw) -replace '(?m)^(.*?):','$1=' | ConvertFrom-StringData
# read the 'Add.bat' as string array
$bat = (Get-Content -Path 'D:TestAdd.bat') | ForEach-Object {
if ($_ -match '^Reg.*/vs+"([^"]+)".*"(tochange)"') {
if ($pcHash.ContainsKey($matches[1])) {
# output this line updated
$_ -replace $matches[2], $pcHash[$matches[1]]
}
}
else {
# output the line unchanged
$_
}
}
# output to (new) file. -PassThru will also show the result on screen
$bat | Set-Content -Path 'D:TestNew.bat' -PassThru
结果:
@Echo Off
cd %systemroot%system32
Reg.exe add "HKCUSoftwareHPHPTwain" /v "DesktopShortcut" /t REG_SZ /d "Yes" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "ModelName" /t REG_SZ /d "HP Color LaserJet Pro M478fxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "HostName" /t REG_SZ /d "EPxxxxxx" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "IP Address" /t REG_SZ /d "192.x.x.x" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "SerialNo" /t REG_SZ /d "CNBxx3P8WY" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Services" /t REG_SZ /d "PclPrint eSCL LEDM" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "NetworkType" /t REG_SZ /d "Ethernet" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "MAC" /t REG_SZ /d "c4651645xxb95" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "Manufacturer" /t REG_SZ /d "Hewlett-Packard" /f
Reg.exe add "HKCUSoftwareHPHPTwain" /v "GUID" /t REG_SZ /d "urn:uuid:8866a4ce-2da1-5b24-6af5-13e5dc7f63b5" /f
xcopy "C:applicationsTwainConfig*" "%USERPROFILE%AppDataLocal" /s /i /Y
Cls
Exit
Regex细节:
^ Assert position at the beginning of the string
Reg Match the characters “Reg” literally
. Match any single character that is not a line break character
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
/v Match the characters “/v” literally
s Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
" Match the character “"” literally
( Match the regular expression below and capture its match into backreference number 1
[^"] Match any character that is NOT a “"”
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
" Match the character “"” literally
. Match any single character that is not a line break character
* Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
" Match the character “"” literally
( Match the regular expression below and capture its match into backreference number 2
tochange Match the characters “tochange” literally
)
" Match the character “"” literally