一 需求引入
① echo处于打开状态
+++++++'变量没有与=进行连接导致'+++++++
set aa ="123"
echo %aa%
① 测试1
需求:'遍历'文件的'每一行'
1) 预处理回显-->@echo off-->不在终端显示,只在'modify文件'中显示
2) 原因:%i%'没有获取'到值 -->"为什么?"
批处理中echo回显的问题:空变量在BAT和CMD中的结果不同
(echo.%var%)>1.txt
>1.txt echo.%var%
解读: >重定向输出'放到哪里'都可以;而'放到开头'既可以'保证'前面'没有数字被解释为句柄',也可以保证后面的echo'正常打印'
细节:输入的字符串最后'包含数字'的情况
② 小技巧
说明:当前重点是echo.%str% -->echo.!str! -->'重点理解'
③ 参考链接
需求:把其中的'测试'换成'test'-->需要正确处理'空行'和'特殊符号!'
REM UTF-8编码 -->可以设置> null
chcp 65001
@echo off
for /f "tokens=*" %%a in ('findstr /n .* c.txt') do (
REM 备注:除了文本是以 "冒号(:)"和"分号(;)"开头会'出错'外,其它文本字符'不会有问题'了
set tmp=%%a
setlocal enabledelayedexpansion
REM 必须'先set赋值'才能使用'!!'
set tmp=!tmp:测试=test!
REM 把 '冒号前'的'丢弃'掉-->原因(findstr引入的)
REM 备注:自己是通过"字符截取"得到的
REM 备注-->echo;和echo.'等价'
echo;!tmp:*:=!
endlocal
)
REM 注意'enabledelayedexpansion(变量延迟加载)'和'endlocal'的'作用范围'-->'尽量缩小'
④ 探究默认行为
+++++++++'默认行为'+++++++++
1) 默认'eol=;',所以以'分号开头的行'会被自动删除
2) 默认'delims=(空格)',而'tokens=1',所以打印'第一列'的值
3) 以'多个空格'开头的会被'删除'
⑤ 进阶
1) 从'③'我们知道利用'字符串'的替换达到我们的'需求'
2) 那被'替换'的字符串本身包含"!" -->"如何解决?"
(1)尝试1
需求:将'! FUNCTION'替换为'FUNCTION',其余的'不变'
强调:bat的文本处理,具体场景'具体分析',不能'一招鲜吃遍天'
细节:"tokens=*" 表示获取行上的所有内容,但是会忽略'行首为空格的行'-->'自己测试'
备注:'别人'-->但是会忽略'行首的所有空格'
(2)尝试2
早期:以'!开头'的行,'!会被删除' -->setlocal的'时机不对'
备注:这里通过"字符截取"得到
需求:只'替换'该替换的,其余的原样输出;保留感叹号、保留空行 -->不涉及";"开头的行
备注:最好'加上'@echo off
+++++++++'解决的问题-->保留空行替换字符串'+++++++++
1) '不会忽略'以";"开头的行-->'find /n'的作用
2) '不会删除'以"!"开头行的"!"字符-->'find /n'的作用
3) '不会删除'空行-->"echo."作用
⑥ 最佳实践
1) findstr /n 处理得到的行格式是--> '行号:原文'
2) set var=!var:*:=! 的目的是'去掉第一个冒号前面的内容(行号:)',以得到原行
⑦ tokens和delims理解
1) "delims=" 的含义是'取消默认'的分隔符,所以会把行上的内容'照搬'下来
理解:类似"set a="-->'删除'一个变量
2) 而 "tokens=*" 表示'获取行上'的所有内容,但是会'忽略行首'的所有'空格'
3) delims=写在后面-->如果'写在前面'中间的空格也会被当作'分隔符集'中的一个-->多个"options"
举例:for /f "tokens=* delims=" in
1)%i 这一个'比较特殊',因为它'不是批处理文件中的变量',只能'用于cmd命令行下'的for循环中
2)%%i 这种类型也是'bat脚本'中'for循环中'特有的,与%i相对,属于'批处理程序'的用法
3)!i! 在 for /f 解读参数时'尚未被解释为'变量;而对 %i% 的解释'发生'在 for /f '解读参数之前'