标题: [文本处理] [已解决]批处理如何根据输入的字符串替换文本里固定行中的固定字符后面4位 [打印本页]
作者: zidha 时间: 2019-8-4 09:38 标题: [已解决]批处理如何根据输入的字符串替换文本里固定行中的固定字符后面4位
本帖最后由 zidha 于 2019-8-5 19:05 编辑
我有一个1.xml文件,想修改文件里固定行数的字符串,如下只截取了一部分:- <component name="Microsoft">
- <ComputerName>PCZF0001</ComputerName>
- <TimeZone>China Standard time</TimeZone>
- </component>
复制代码
我想修改这行 <ComputerName>PCZF0001</ComputerName>的PCZF0001,PCZF001后边的4个数字是不确定的;
需要手动输入,如输入0002,就如下:
<ComputerName>PCZF0002</ComputerName>
如输入0003,就如下:
<ComputerName>PCZF0003</ComputerName>
如输入0999,就如下:
<ComputerName>PCZF0999</ComputerName>
以此类推,如何用批处理修改,先谢谢了。
作者: flashercs 时间: 2019-8-4 10:26
这是改计算机名?
把0001 改为 0004 之类?
作者: zidha 时间: 2019-8-4 10:37
回复 2# flashercs
是的
作者: flashercs 时间: 2019-8-4 11:40
本帖最后由 flashercs 于 2019-8-4 20:36 编辑
- @echo off
- Powershell -Command "$flag = $false; $sb = $ExecutionContext.InvokeCommand.NewScriptBlock((Get-Content -LiteralPath \"%~0\" | ForEach-Object { if ($flag) { $_ }else { if ($_ -match '#+Powershell#+') { $Script:flag = $true } } }) -join \"`r`n\"); & $sb "
- pause
- exit /b
- ########Powershell########
- # XML文件路径
- $xmlpath = "E:\test\new folder\zuma\1.xml"
- # 计算机名前缀
- $prefix = "PCZF"
- function MakeDOM {
- param (
-
- )
- $dom = try {
- New-Object -ComObject 'Msxml2.DOMDocument.6.0'
- }
- catch {
- try {
- New-Object -ComObject 'Msxml2.DOMDocument.3.0'
- }
- catch {
- try {
- New-Object -ComObject 'Msxml2.DOMDocument'
- }
- catch {
- throw
- }
- }
- }
- $dom.async = $false
- $dom.validateOnParse = $false
- $dom.resolveExternals = $false
- $dom.setProperty('AllowDocumentFunction', $false)
- $dom.setProperty('AllowXsltScript', $false)
- $dom.setProperty('MaxElementDepth', 256)
- $dom.setProperty('ProhibitDTD', $true)
- $dom.setProperty('SelectionLanguage', 'XPath')
- return $dom
- }
-
- function parseError {
- param(
- $dom
- )
- $myErr = $dom.parseError
- if ($myErr.errorCode -ne 0) {
- Write-Host -InputObject "XML parse error" -ForegroundColor Red
- Out-Host -InputObject @{
- 'reason' = myErr.reason;
- 'code' = myErr.errorCode.toUIString(16);
- 'filepos' = myErr.filepos;
- 'line' = myErr.line;
- 'linepos' = myErr.linepos;
- 'srcText' = myErr.srcText;
- 'url' = myErr.url
- }
- return $true
- }
- return $false
- }
- $xmldoc = MakeDOM
- try {
- $xmldoc.load($xmlpath) | Out-Null
- if (parseError $xmldoc) {
- throw
- }
- do {
- $dic = $host.UI.Prompt('Modify XML', '请输入替换前和替换后的字符串:', @('From', 'To'))
- try {
- $xmldoc.SelectSingleNode("//ComputerName[text()=`"$prefix$($dic.From)`"]/text()").nodeValue = $prefix + $dic.To
- Write-Host "Success" -ForegroundColor Green
- }
- catch {
- Write-Host "Failed" -ForegroundColor Green
- }
- $choice = $host.UI.PromptForChoice('继续修改', '是否继续?', @([System.Management.Automation.Host.ChoiceDescription]::new('Y', 'Yes'), [System.Management.Automation.Host.ChoiceDescription]::new('N', 'No')), 0)
- } until ($choice)
-
- $xmldoc.save($xmlpath)
- }
- catch {
-
- }
- finally {
- [System.Runtime.InteropServices.Marshal]::ReleaseComObject($xmldoc) | Out-Null
- Remove-Variable -Name xmldoc
- [gc]::collect()
- [gc]::WaitForPendingFinalizers()
- }
复制代码
作者: zidha 时间: 2019-8-4 12:41
flashercs 发表于 2019-8-4 11:40
谢谢你的解答!
我试了下但报错,- True
-
- Modify XML
- 请输入需要替换的字符串:
- From: 8888
- To: 3333
- 在此对象上找不到属性“nodeValue”。请确认该属性存在并且可设置。
- 所在位置 行:35 字符: 60
- + ... .SelectSingleNode("//ComputerName[text()=`"$prefix$($dic.From)`"]/tex ...
- + ~~~~~~~~~
- + CategoryInfo : InvalidOperation: (:) [],RuntimeException
- + FullyQualifiedErrorId : PropertyNotFound
-
- 请按任意键继续. . .
复制代码
可不可是纯批处理脚本,因为我要在WinPE下运行的;
还有就是最好就是直接修改,不要输入原来字串,因为不能每次使用时打开文件查看一下PCZF后面4个字符。
作者: /zhqsystem/zhq 时间: 2019-8-4 13:49
给你弄个直接创建9999个的吧,用哪个复制哪个,注意格式必须与样本保持一致
示例代码:有些东西和路径自己替换- SetLocal EnableDelayedExpansion
- set "component="&&for /f "delims=" %%i in ('type "1.txt"')do if /i "%%i"==" </component>" (set "component=True")else (
- if defined component (>>".\PCZFxxxx.xml" echo,%%i)
- )
- for /f "delims=" %%i in ('type "1.txt"')do if /i "%%i"==" </component>" (
- for /l %%n in (0,1,9999)do (set "#=0000%%n"
- >".\PCZF!#:~-4!.xml" (
- call:1 PCZF!#:~-4!
- type ".\PCZFxxxx.xml"
- )
- )
- )
- del/q ".\PCZFxxxx.xml"
- pause
- goto:eof
- :1
- echo,^<component name="Microsoft"^>
- echo, ^<ComputerName^>%*^</ComputerName^>
- echo, <TimeZone^>China Standard time^</TimeZone^>
- echo, ^</component^>
- goto:eof
复制代码
作者: zaqmlp 时间: 2019-8-4 14:16
- @echo off
- set info=互助互利,支付宝扫码头像,感谢赞助
- rem 有问题,可加QQ956535081及时沟通
- cd /d "%~dp0"
- set "infile=1.xml"
- set "outfile=2.xml"
- set /p input=输入编号:
- for /f "delims=:" %%a in ('findstr /n "<ComputerName>" "%infile%"') do set #%%a=1
- (for /f "tokens=1* delims=:" %%a in ('findstr /n .* "%infile%"') do (
- if defined #%%a (
- echo; ^<ComputerName^>PCZF%input%^</ComputerName^>
- ) else echo;%%b
- ))>t.t
- move /y t.t "%outfile%"
- echo;%info%
- pause
复制代码
作者: zidha 时间: 2019-8-4 18:12
回复 6# /zhqsystem/zhq
我要的是修改文件内的字符,不是文件名;我把论坛的“批处理For语句从入门到精通(完整版)”读了一遍也没能在你的文件上修改成功
我是新手,能力有限,7楼的朋友已经帮我解决了,不过还是感谢你的解答。
我找了个批处理但是有些问题如下:- @echo off&setlocal enabledelayedexpansion
- ren abc.xml abc.txt
- set /p pcname=Name:
- for /f "delims=" %%a in (abc.txt) do (
- set /a num+=1
- if !num!==88 (echo " <ComputerName>!pcname!</ComputerName>") else echo %%a
- )>>abc.xml
- del abc.txt
- pause
复制代码
修改后的那行总是被添加了两个""如下:- " <ComputerName>8888</ComputerName>"
复制代码
但去掉就闪退,”“去掉后,文字里的"<”“>”可能被识别成命令符了。
作者: zidha 时间: 2019-8-4 18:17
回复 7# zaqmlp
非常感谢你,这个脚本可以达到我要的结果;
还想请教个问题,直接修改原文件而不生成新文件,需要怎么做,或者指点下需要使用什么命令或哪方面资料吗?
作者: Batcher 时间: 2019-8-4 18:53
回复 9# zidha
7楼14行改成这样试试:
move /y t.t "%infile%"
作者: Batcher 时间: 2019-8-4 18:55
回复 8# zidha
特殊字符可以用^转义试试
http://bbs.bathome.net/thread-1205-1-1.html#pid25363
作者: zidha 时间: 2019-8-4 20:28
回复 10# Batcher
非常感谢!这样是可以的,但中间不生成临时文件可以吗?
作者: flashercs 时间: 2019-8-4 20:33
回复 12# zidha
没有临时文件- @echo off
- set "xmlfile=%~dp01.xml"
- set /p input=输入编号:
- for /f "delims=:" %%a in ('findstr /n "<ComputerName>" "%xmlfile%"') do set #%%a=1
- for /f "tokens=1* delims=:" %%a in ('"2>nul,findstr /n .* "%xmlfile%"&&<nul,>"%xmlfile%",set /p="') do (
- if defined #%%a (
- >>"%xmlfile%",echo, ^<ComputerName^>PCZF%input%^</ComputerName^>
- ) else >>"%xmlfile%",echo,%%b
- )
- pause
- exit /b
复制代码
作者: zidha 时间: 2019-8-4 20:37
回复 11# Batcher
太感谢了,看了“转帖:批处理中符号的作用”再参考7楼的脚本,修改了下我之前的找到脚本也可以达到效果了。- @echo off&setlocal enabledelayedexpansion
- ren abc.xml abc.txt
- set /p pcname=Name:
- for /f "delims=" %%a in (abc.txt) do (
- set /a num+=1
- if !num!==88 (echo ^<ComputerName^>PCZF!pcname!^</ComputerName^>) else echo %%a
- )>>abc.xml
- del abc.txt
- pause
复制代码
作者: xczxczxcz 时间: 2019-8-4 21:04
都搞这么复杂?- $enter =Read-Host "输入序号";
- $f ="$(gl)\a.xml";
- [xml]$file =gc $f -ReadCount 0;
- $file.component.ComputerName='FCZF'+$enter;
- $file.Save($f);
- cmd /c pause
复制代码
作者: Batcher 时间: 2019-8-5 09:22
回复 12# zidha
容易导致文件内容丢失。不建议那样做。
作者: zidha 时间: 2019-8-5 19:15
回复 15# xczxczxcz
谢谢!Powershell是很强大,但WinPE下兼容问题不好解决;我把7楼的脚本在WinPE下跑了下,
本地系统测试过的,没问题,就跑出来“findstr”不是内部命令不支持的问题,
最后提取Win10系统里“findstr.exe”文件封进启动映像里才解决。
作者: zidha 时间: 2019-8-5 19:16
回复 16# Batcher
收到,非常感谢!
作者: WHY 时间: 2019-8-5 20:35
本帖最后由 WHY 于 2019-8-5 20:41 编辑
- @echo off
- set /p input=input:
- (for /f "delims=" %%i in (a.xml) do (
- set "str=%%i"
- setlocal enabledelayedexpansion
- if "!str:<ComputerName>=!" NEQ "!str!" (
- echo; ^<ComputerName^>PCZF!input!^</ComputerName^>
- ) else (echo;!str!)
- endlocal
- )) > b.xml
- move b.xml a.xml
- pause
复制代码
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |