[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文件操作] 批处理如何只对文本中的首个/第一个出现的指定字符/字符串进行替换

本帖最后由 pcl_test 于 2016-10-20 14:04 编辑

(搜过了,但是我找不到)
需要求问的部分:
(下面的%a%是txt文件的目录,%n%和%e%都是设置过的)
  1. for /f "delims=" %%i in (%a%) do (
  2. set var=%%i
  3. set var=!var:%n%=%e%!
  4. echo !var! >>a.txt
  5. )
  6. del %a%
  7. ren a.txt b.txt
复制代码
这样的话,全部的%n%代指的内容都会被替换为%e%,可是我只需要替换第一个%n%(替换的是数字,如果全替换的话就会导致本来只要替换1为2,结果12也变成了22)
请问该怎么改代码?
(纯Bat)
1

评分人数

!var! 是从文本文件中读出的一行, %n% 是你要替换的字符, %e% 是你要替换成的字符, # 假设是你文本中不会含有的字符
另外假设 要替换的字符 和 要替换成的字符 都不是一些有语法作用的特殊字符
  1. for /f "tokens=1* delims=%n%" %a in ("#!var!") do echo;%%a%e%%%b
复制代码
1

评分人数

TOP

本帖最后由 hongrk 于 2016-10-20 17:42 编辑

回复 2# aa77dd@163.com
事实上你这个代码用处不大,因为你这样的话读取需要的那行依旧问题没变。不过改一些内容应该就可以用了。如果改完之后能用了,那就解决了。

TOP

举个栗子
  1. @echo off&setlocal enabledelayedexpansion
  2. set a=1
  3. set b=@
  4. set c=%a%fedcba9876543210
  5. set /a n=0x%c:~15,1%
  6. for /f "delims=" %%a in ('more +25 "%~f0"') do (
  7.     set "str=%%a"
  8.     if "!str:%a%=!" equ "%%a" (
  9.         echo;%%a
  10.     ) else (
  11.         if not defined f (
  12.             call :loop
  13.             set f=1
  14.         ) else echo;%%a
  15.     )
  16. )
  17. pause&exit
  18. :loop
  19. for /l %%i in (0 1 8190) do (
  20.     if "!str:~%%i,%n%!" equ "%a%" (
  21.         set /a m=%%i+n
  22.         for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
  23.         goto :eof
  24.     )
  25. )
  26. 11ad3inm1di33
  27. 3eir11eeed2e1
  28. 22131e3iee1en
复制代码
1

评分人数

TOP

回复 4# pcl_test
也许可以,不过我看不懂。我把不懂的地方发出来,你如果愿意解释的话就帮忙一下,如果不行的话就算了。因为如果没看到你这个回复的话,我是已经打算一个个替换过去不用循环了。
  1. set /a n=0x%c:~15,1%
复制代码
(这个设置怎么也看不懂啊..)
  1. if "!str:%a%=!" equ "%%a" (
  2. echo;%%a
  3. )
复制代码
(把%str%里的%a%替换为空,如果和%%a相等就echo %%a吗?怎么想也不明白。)
  1. if not defined f (
  2. call :loop
  3. set f=1
  4. )
复制代码
(如果%f%被定义,就调用:loop,设%f%为1。不明觉厉。)
  1. if "!str:~%%i,%n%!" equ "%a%" (
  2. set /a m=%%i+n
  3. for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
  4. goto :eof
  5. )
复制代码
(第一行前面的部分就看不懂了。另外那些;是干啥用的?而且这些代码里好像没有:eof,那那个goto是干啥用的?)

(主要就这些问题不懂,其他的一些问题有的去搜了下就找到了。虽然总体根本看不懂,不过这些问题解决了之后也许就看得懂了。)

TOP

本帖最后由 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、如果替换掉指定字符或字符串不变则直接输出,即不包含指定字符或字符串则直接输出,如
  1. set a=123
  2. set a=%a:4=%
  3. echo;%a%
  4. set a=%a:2=%
  5. echo;%a%
  6. 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子过程亦可用以下方法
  1. :loop
  2. set "s=!str:*%a%=!#"
  3. 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!
  4. set s=!s!fedcba9876543210&set/am+=0x!s:~16,1!
  5. for %%j in (!m!) do for /f %%k in ('set/an+m') do if !m! equ 0 (
  6.     echo;!str:~,-%%k!%b%
  7. ) else echo;!str:~,-%%k!%b%!str:~-%%j!
  8. goto :eof
  9. 11ad3inm1di33
  10. 3eir11eeed2e1
  11. 22131e3iee1en
复制代码
1

评分人数

    • hongrk: 有点晕乎,但基本明白了技术 + 1

TOP

回复 6# pcl_test
  1. for /l %%i in (0 1 8190) do (
复制代码
其中的1 可以改为%n%吗?   因为不止要替换1个数,其中肯定会存在长度不同的字符串的。不过需要替换的数最多也就4位数,弄16位数有点多了,我改一下代码你看看行不。
  1. set c=%a%43210
  2. set /a n=%c:~4,1%
复制代码
因为要循环,我把代码改了改:
  1. @echo off&setlocal enabledelayedexpansion
  2. set a=1
  3. set b=@
  4. set c=%a%fedcba9876543210
  5. set /a n=0x%c:~15,1%
  6. call :0
  7. call :1
  8. cls&pause&exit
  9. :loop
  10. for /l %%i in (0 1 8190) do (
  11. if "!str:~%%i,%n%!" equ "%a%" (
  12. set /a m=%%i+n
  13. for %%j in (!m!) do echo;!str:~,%%i!%b%!str:~%%j!
  14. goto :eof
  15. )
  16. )
  17. :0
  18. for /f "delims=" %%a in ('more +35 "%~f0"') do (
  19. set "str=%%a"
  20. if "!str:%a%=!" equ "%%a" (
  21. echo;%%a
  22. ) else (
  23. if not defined f (
  24. call :loop
  25. setlocal
  26. set f=1
  27. ) else echo;%%a&pause&goto :eof
  28. )
  29. )
  30. :1
  31. set a=2
  32. set b=#
  33. set c=%a%fedcba9876543210
  34. set /a n=0x%c:~15,1%&endlocal
  35. call :0
  36. 11ad3inm1di33
  37. 3eir11eeed2e1
  38. 22131e3iee1en
复制代码
可是运行的时候,第一遍只会出现前两行,第三行到第二遍才出现。这是为什么?

TOP

返回列表