标题: [文件操作] 批处理如何只对文本中的首个/第一个出现的指定字符/字符串进行替换 [打印本页]
作者: hongrk 时间: 2016-10-20 13:24 标题: 批处理如何只对文本中的首个/第一个出现的指定字符/字符串进行替换
本帖最后由 pcl_test 于 2016-10-20 14:04 编辑
(搜过了,但是我找不到)
需要求问的部分:
(下面的%a%是txt文件的目录,%n%和%e%都是设置过的)- for /f "delims=" %%i in (%a%) do (
- set var=%%i
- set var=!var:%n%=%e%!
- echo !var! >>a.txt
- )
- del %a%
- ren a.txt b.txt
复制代码
这样的话,全部的%n%代指的内容都会被替换为%e%,可是我只需要替换第一个%n%(替换的是数字,如果全替换的话就会导致本来只要替换1为2,结果12也变成了22)
请问该怎么改代码?
(纯Bat)
作者: aa77dd@163.com 时间: 2016-10-20 13:48
!var! 是从文本文件中读出的一行, %n% 是你要替换的字符, %e% 是你要替换成的字符, # 假设是你文本中不会含有的字符
另外假设 要替换的字符 和 要替换成的字符 都不是一些有语法作用的特殊字符- for /f "tokens=1* delims=%n%" %a in ("#!var!") do echo;%%a%e%%%b
复制代码
作者: hongrk 时间: 2016-10-20 17:18
本帖最后由 hongrk 于 2016-10-20 17:42 编辑
回复 2# aa77dd@163.com
事实上你这个代码用处不大,因为你这样的话读取需要的那行依旧问题没变。不过改一些内容应该就可以用了。如果改完之后能用了,那就解决了。
作者: pcl_test 时间: 2016-10-20 20:03
举个栗子- @echo off&setlocal enabledelayedexpansion
- set a=1
- set b=@
- set c=%a%fedcba9876543210
- set /a n=0x%c:~15,1%
- for /f "delims=" %%a in ('more +25 "%~f0"') do (
- set "str=%%a"
- if "!str:%a%=!" equ "%%a" (
- echo;%%a
- ) else (
- if not defined f (
- call :loop
- set f=1
- ) else echo;%%a
- )
- )
- pause&exit
- :loop
- for /l %%i in (0 1 8190) do (
- if "!str:~%%i,%n%!" equ "%a%" (
- set /a m=%%i+n
- for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
- goto :eof
- )
- )
- 11ad3inm1di33
- 3eir11eeed2e1
- 22131e3iee1en
复制代码
作者: hongrk 时间: 2016-10-20 20:53
回复 4# pcl_test
也许可以,不过我看不懂。我把不懂的地方发出来,你如果愿意解释的话就帮忙一下,如果不行的话就算了。因为如果没看到你这个回复的话,我是已经打算一个个替换过去不用循环了。复制代码
(这个设置怎么也看不懂啊..)- if "!str:%a%=!" equ "%%a" (
- echo;%%a
- )
复制代码
(把%str%里的%a%替换为空,如果和%%a相等就echo %%a吗?怎么想也不明白。)- if not defined f (
- call :loop
- set f=1
- )
复制代码
(如果%f%被定义,就调用:loop,设%f%为1。不明觉厉。)- if "!str:~%%i,%n%!" equ "%a%" (
- set /a m=%%i+n
- for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
- goto :eof
- )
复制代码
(第一行前面的部分就看不懂了。另外那些;是干啥用的?而且这些代码里好像没有:eof,那那个goto是干啥用的?)
(主要就这些问题不懂,其他的一些问题有的去搜了下就找到了。虽然总体根本看不懂,不过这些问题解决了之后也许就看得懂了。)
作者: pcl_test 时间: 2016-10-20 22:08
本帖最后由 pcl_test 于 2016-10-20 23:46 编辑
回复 5# hongrk
相关知识
for
call
set /a
变量延迟
字符串长度计算
字符串替换及截取
1、16进制数转10进制数
fedcba9876543210表示10进制数15~0,如set /a 0xf得15,set /a 0xa得10……
set /a n=0x%c:~15,1% 利用偏移量获取相应16进制数转10进制数,如1111fedcba9876543210,截取第16位为4,所以1111的长度为4位,0123456789fedcba9876543210,截取第16位为a,所以0123456789的长度为10位
2、如果替换掉指定字符或字符串不变则直接输出,即不包含指定字符或字符串则直接输出,如- set a=123
- set a=%a:4=%
- echo;%a%
- set a=%a:2=%
- echo;%a%
- pause
复制代码
3、对首个出现的指定字符/字符串进行替换并做标记f=1,对于余下同样包含指定字符/字符串的行,因为做了标记则直接输出
4、对于同一行含有多个指定字符/字符串的情况,利用偏移查找出首个出现的指定字符/字符串,
如123123,需替换第一个23为##,计算所知23长度为2位,那么对于123123,从第1位开始偏移,每次偏移/截取2位,则有
12 3123
1 23 123 //当截取内容等于需替换的字符/字符串,则输出1##123实现替换,goto :eof执行退出for /l循环和loop子过程
12 31 23
123 12 3
1231 23
12312 3
loop子过程亦可用以下方法- :loop
- set "s=!str:*%a%=!#"
- set m=0&for %%i in (4096 2048 1024 512 256 128 64 32 16) do if "!s:~%%i,1!" neq "" set/am+=%%i&set s=!s:~%%i!
- set s=!s!fedcba9876543210&set/am+=0x!s:~16,1!
- for %%j in (!m!) do for /f %%k in ('set/an+m') do if !m! equ 0 (
- echo;!str:~,-%%k!%b%
- ) else echo;!str:~,-%%k!%b%!str:~-%%j!
- goto :eof
- 11ad3inm1di33
- 3eir11eeed2e1
- 22131e3iee1en
复制代码
作者: hongrk 时间: 2016-10-21 13:02
回复 6# pcl_test - for /l %%i in (0 1 8190) do (
复制代码
其中的1 可以改为%n%吗? 因为不止要替换1个数,其中肯定会存在长度不同的字符串的。不过需要替换的数最多也就4位数,弄16位数有点多了,我改一下代码你看看行不。- set c=%a%43210
- set /a n=%c:~4,1%
复制代码
因为要循环,我把代码改了改:- @echo off&setlocal enabledelayedexpansion
- set a=1
- set b=@
- set c=%a%fedcba9876543210
- set /a n=0x%c:~15,1%
- call :0
- call :1
- cls&pause&exit
- :loop
- for /l %%i in (0 1 8190) do (
- if "!str:~%%i,%n%!" equ "%a%" (
- set /a m=%%i+n
- for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
- goto :eof
- )
- )
- :0
- for /f "delims=" %%a in ('more +35 "%~f0"') do (
- set "str=%%a"
- if "!str:%a%=!" equ "%%a" (
- echo;%%a
- ) else (
- if not defined f (
- call :loop
- setlocal
- set f=1
- ) else echo;%%a&pause&goto :eof
- )
- )
- :1
- set a=2
- set b=#
- set c=%a%fedcba9876543210
- set /a n=0x%c:~15,1%&endlocal
- call :0
- 11ad3inm1di33
- 3eir11eeed2e1
- 22131e3iee1en
复制代码
可是运行的时候,第一遍只会出现前两行,第三行到第二遍才出现。这是为什么?
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |