[初步解决]请问findstr表达式配合set的通配符引用为什么会无效
本帖最后由 cii09 于 2024-4-21 13:38 编辑===初步解决=======
感谢szwp,junyee的帮助
方法1 9#
方法2 18#
=====
bat批处理findstr配合set修改文本配置文件,匹配文件名指定行的路径地址,
绿色软件修复配置文件中路径地址到当前目录
=====
请问findstr正则表达式引用为什么会无效
=====
请问set "b=!a:%oldStr%=%newStr%!"正则表达式引用为什么会无效
=====
bat绿色软件路径修复脚本,findstr变量路径正则表达式应该怎么写东拼西凑出来的很烂,辣眼见谅
::replace.bat
@echo off
set dd=%DATE:~8,2%
set mm=%DATE:~5,2%
set yy=%DATE:~0,4%
set Tss=%TIME:~6,2%
set Tmm=%TIME:~3,2%
set Thh=%TIME:~0,2%
set Thh=%Thh: =0%
::ECHO %yy%%mm%%dd%-%Thh%%Tmm%%Tss%.txt
setlocal enabledelayedexpansion
REM orginalFile原始要操作的文件,单个文件。注:替换的文件中不能有冒号,否则结果不对。或者修改本脚本中for循环的delims=:中冒号为其他在文件中没有出现的符号,其中不能是等于号,<>需要加转义字符^,即写成delims=^<。
set orginalFile=Libraries.Info
REM outputFile指定替换字符串后,输出的文件
set outputFile=Libraries.Info.tmp
REM 最终文件
set finalOutFile=Libraries.Info
REM 设置程序所在
::set localadds=%~dp0test1\
set localadds=%~dp0
REM 要替换的原始字符串
::set oldStr=.\FL.Backups
set "oldStr=FL.Backups[ DISCUZ_CODE_0 ]quot;
REM 替换后的字符串
set newStr=%localadds%FL.Backups
REM 指定替换找到的第几个字符串,0是指全部替换
set /a number=1
:bakorg
copy %orginalFile% %orginalFile%.bak%yy%%mm%%dd%%Thh%%Tmm%%Tss%
goto replace
:replace
if exist %outputFile% del %outputFile%
set /a i=0
for /f "delims=" %%i in ('findstr /n .* %orginalFile%') do (
set "a=%%i"
set "a=!a:*:=!"
if "!a!"=="" (
set "b=!a!"
) else (
if %number% == 0 (
set "b=!a:%oldStr%=%newStr%!"
) else (
set "b=!a!"
if not "!a!" == "!a:%oldStr%=%newStr%!" (
set /a i+=1
if %number% == !i! (
set "b=!a:%oldStr%=%newStr%!"
)
)
)
)
REM 保留空白行,某行内容是空格或多个空格
echo.!b!>>%outputFile%
)
REM 临时文件改名删除源文件并输出结果文件
if exist %orginalFile% del %orginalFile%
::rename %orginalFile% %orginalFile%.bak
rename %outputFile% %finalOutFile%
set oldStr=.\FL.Backups
我想匹配以FL.Backups结尾的行,应该怎么写可以被正确识别
c:\FH.Backups
.\FL.Backups
d:\FH.Backups2
d:\FH.Backups5
d:\FH.Backups3
d:\FH.Backups20240403
H:\gr\FL.Backups
比如这个例子,替换第4和第9行到D:\test1\FL.Backups,D:\test2\FL.Backups
学习一下看看 看不懂,等老师来讲解下 谢谢分享 谢谢分享 findstr /?
/E 在一行的结尾配对模式。
$ 行位置: 行的终点
是这个意思么? szwp 发表于 2024-4-17 13:27
findstr /?
/E 在一行的结尾配对模式。
$ 行位置: 行的终点
目的就是这样,但是因为51行引用的37行
直接改37行那里
set oldStr=.\FL.Backups
set oldStr=.\FL.Backups$
set oldStr=”.\FL.Backups$“
都是无效的,for循环那里应该也要改,bat的语法不熟,没跑通
cii09 发表于 2024-4-17 13:35
目的就是这样,但是因为51行引用的37行
直接改37行那里
set oldStr=.\FL.Backups
FINDSTR /n /E .\FL.Backups
试一下 szwp 发表于 2024-4-17 13:50
FINDSTR /n /E .\FL.Backups
试一下
rem 测试
:replace2
@echo off
setlocal enabledelayedexpansion
set "inputFile=Libraries.Info"
set "outputFile=Libraries.Info.tmp"
set "searchString=FL.Backups"
set "newPath=%localadds%FL.Backups"
if exist %outputFile% del %outputFile%
(for /f "tokens=*" %%a in ('type "%inputFile%"') do (
set "line=%%a"
set "modifiedLine="
set "tempLine="
for %%b in (!line!) do (
set "token=%%~b"
set "temp=!token:%searchString%=!"
if "!temp!"=="!token!" (
set "tempLine=!tempLine!%%~b "
) else (
set "tempLine=!tempLine!%newPath% "
)
)
rem Remove any leading and trailing non-alphanumeric characters from the line
set "tempLine=!tempLine:>*[^A-Za-z0-9]=!"
set "tempLine=!tempLine:~0,-1!"
echo !tempLine!
)) > "%outputFile%"
echo "Replacement complete."
endlocal
goto finalOutput这样写可以用,就是蠢了一点,不知道会不会有其他问题
cii09 发表于 2024-4-18 08:47
这样写可以用,就是蠢了一点,不知道会不会有其他问题
将问题简化,无关的代码就不要发了。
szwp 发表于 2024-4-18 09:07
将问题简化,无关的代码就不要发了。
前两天试了几次没成功。这样写
set "searchString=FL.Backups$"
...
set "b=!a:%searchString%=%newStr%!"
这个没办法生效,不知道是格式转译问题,还是逻辑问题。现在发不了附件,直接贴看起来就一大坨,见谅 本帖最后由 junyee 于 2024-4-21 08:49 编辑
没有看批处理.
1.首先, findstr 支持的不是正则, 帮助里描述的是 "通用表达式"
findstr 的用法,隔壁专业论坛有一个帖子:
批处理命令findstr正则表达式的基本用法
2. 排除掉语法逻辑,批处理对一些特殊字符串处理有很多坑的, 如<>"\=^| 和空格,要特别注意. 还有批处理自身的编码格式,甚至非 \r\n 的换行符都能带来莫名其妙的问题.
本帖最后由 junyee 于 2024-4-21 08:56 编辑
cii09 发表于 2024-4-18 09:38
前两天试了几次没成功。这样写
set "searchString=FL.Backups$"
...
把发现有疑问处单独拎出来,自己写一个完整的测试脚本.
不要让有心帮忙的人看一堆垃圾代码.人家测试是无偿的帮助,还要给你揣测用意+写测试脚本
?????
@echo off
setlocal enabledelayedexpansion
set a="123456FL.Backups$7890"
set "searchString=FL.Backups$"
set newStr=####
set "b=!a:%searchString%=%newStr%!"
echo %b%
pause
junyee 发表于 2024-4-21 08:53
把发现有疑问处单独拎出来,自己写一个完整的测试脚本.
不要让有心帮忙的人看一堆垃圾代码.人家测试是无 ...
set 不生效的原因是,没有启用变量延迟扩展.
也就是上面第二行.
setlocal enabledelayedexpansion
写起来很长是不是,能不能简化?不能.写着写着就能记住 了.
本帖最后由 cii09 于 2024-4-21 11:21 编辑
junyee 发表于 2024-4-21 08:58
set 不生效的原因是,没有启用变量延迟扩展.
也就是上面第二行.
顶楼贴的第16行已经启用了延迟变量,因为定位不到故障点,能力不足无法精简问题了。
实在没办法在#9的替代方案中甚至弃用了findstr,使用for循环傻换。
因为是拼凑的代码,我其实不是很明白延迟变量 set "b=!a:%oldStr%=%newStr%!" 和 前置全局变量set "oldStr=FL.Backups$"
的实际执行顺序
在简易测试中可以替换成功,可是一旦带到实例中就识别不到全局变量。
补充:
#6
$ 行位置: 行的终点
"oldStr=FL.Backups$" 这个目的是为了匹配以FL.Backups结尾的行,是不是延迟变量里面不可以这么写,需要怎么修改
在问findstr还是set? szwp 发表于 2024-4-21 11:38
在问findstr还是set?
这两个配合起来跑不通,set里面可以支持$吗 cii09 发表于 2024-4-21 11:07
顶楼贴的第16行已经启用了延迟变量,因为定位不到故障点,能力不足无法精简问题了。
实在没办法在#9的替 ...
能力不足就更要多学习.
精力不足就出悬赏帖,隔壁论坛有版块.
请用最简练的文字描述问题,并给出测试环境(脚本/文件).
看了下顶楼的第二部分,给出代码如下,下不为例.
@echo off
setlocal enabledelayedexpansion
set "str1=FL.Backups"
set /a cnt=0
for /f "delims=" %%i in (1.txt) do (
call :find_replace "%%~i""%str1%"
)
pause&GOTO:EOF
:find_replace
echo %~1|findstr /V "%str1%$" &&goto:EOF
set "str2=%~1"
set /a cnt+=1
set str2=%str2:!str1!=%
echo D:\test%cnt%\%str1%
goto:EOF
cii09 发表于 2024-4-21 11:59
这两个配合起来跑不通,set里面可以支持$吗
仔细看俺回的帖和图,进cmd练 /E 在一行的结尾配对模 junyee 发表于 2024-4-21 12:02
能力不足就更要多学习.
精力不足就出悬赏帖,隔壁论坛有版块.
感谢指点!
印象中隔壁有段时间好久都打不开,以为跑路了,之后就没去过。
页:
[1]