无忧启动论坛

标题: [初步解决]请问findstr表达式配合set的通配符引用为什么会无效 [打印本页]

作者: cii09    时间: 2024-4-16 20:47
标题: [初步解决]请问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变量路径正则表达式应该怎么写东拼西凑出来的很烂,辣眼见谅
  1. ::replace.bat

  2. @echo off

  3. set dd=%DATE:~8,2%
  4. set mm=%DATE:~5,2%
  5. set yy=%DATE:~0,4%
  6. set Tss=%TIME:~6,2%
  7. set Tmm=%TIME:~3,2%
  8. set Thh=%TIME:~0,2%
  9. set Thh=%Thh: =0%

  10. ::ECHO %yy%%mm%%dd%-%Thh%%Tmm%%Tss%.txt


  11. setlocal enabledelayedexpansion

  12. REM orginalFile原始要操作的文件,单个文件。注:替换的文件中不能有冒号,否则结果不对。或者修改本脚本中for循环的delims=:中冒号为其他在文件中没有出现的符号,其中不能是等于号,<>需要加转义字符^,即写成delims=^<。
  13. set orginalFile=Libraries.Info
  14. REM outputFile指定替换字符串后,输出的文件
  15. set outputFile=Libraries.Info.tmp
  16. REM 最终文件
  17. set finalOutFile=Libraries.Info
  18. REM 设置程序所在
  19. ::set localadds=%~dp0test1\
  20. set localadds=%~dp0
  21. REM 要替换的原始字符串
  22. ::set oldStr=.\FL.Backups
  23. set "oldStr=FL.Backups[        DISCUZ_CODE_0        ]quot;
  24. REM 替换后的字符串
  25. set newStr=%localadds%FL.Backups
  26. REM 指定替换找到的第几个字符串,0是指全部替换
  27. set /a number=1


  28. :bakorg
  29. copy %orginalFile% %orginalFile%.bak%yy%%mm%%dd%%Thh%%Tmm%%Tss%

  30. goto replace
  31. :replace
  32. if exist %outputFile% del %outputFile%
  33. set /a i=0
  34. for /f "delims=" %%i in ('findstr /n .* %orginalFile%') do (
  35.         set "a=%%i"
  36.         set "a=!a:*:=!"
  37.         if "!a!"=="" (
  38.                 set "b=!a!"
  39.         ) else (
  40.                 if %number% == 0 (
  41.                         set "b=!a:%oldStr%=%newStr%!"
  42.                 ) else (
  43.                         set "b=!a!"
  44.                         if not "!a!" == "!a:%oldStr%=%newStr%!" (
  45.                                 set /a i+=1
  46.                                 if %number% == !i! (
  47.                                         set "b=!a:%oldStr%=%newStr%!"
  48.                                 )
  49.                         )
  50.                 )
  51.         )

  52.         REM 保留空白行,某行内容是空格或多个空格
  53.         echo.!b!>>%outputFile%

  54. )
  55.         REM 临时文件改名删除源文件并输出结果文件
  56.         if exist %orginalFile% del %orginalFile%
  57.         ::rename %orginalFile% %orginalFile%.bak
  58.         rename %outputFile% %finalOutFile%
复制代码

set oldStr=.\FL.Backups

我想匹配以FL.Backups结尾的行,应该怎么写可以被正确识别

  1. [LIBRARIES]
  2. c:\FH.Backups
  3. .\FL.Backups
  4. d:\FH.Backups2
  5. d:\FH.Backups5
  6. d:\FH.Backups3
  7. d:\FH.Backups20240403
  8. H:\gr\FL.Backups
复制代码

比如这个例子,替换第4和第9行到D:\test1\FL.Backups,D:\test2\FL.Backups









作者: 2012飘水    时间: 2024-4-16 21:08
学习一下看看
作者: ningzhonghui    时间: 2024-4-16 21:18
看不懂,等老师来讲解下
作者: wang1126    时间: 2024-4-17 06:39
谢谢分享
作者: nathan6498    时间: 2024-4-17 13:06
谢谢分享
作者: szwp    时间: 2024-4-17 13:27
findstr /?
/E         在一行的结尾配对模式。
  $        行位置: 行的终点

是这个意思么?
作者: cii09    时间: 2024-4-17 13:35
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的语法不熟,没跑通

作者: szwp    时间: 2024-4-17 13:50
cii09 发表于 2024-4-17 13:35
目的就是这样,但是因为51行引用的37行
直接改37行那里
set oldStr=.\FL.Backups

FINDSTR /n /E .\FL.Backups
试一下
作者: cii09    时间: 2024-4-18 08:47
szwp 发表于 2024-4-17 13:50
FINDSTR /n /E .\FL.Backups
试一下
  1. rem 测试
  2. :replace2
  3. @echo off
  4. setlocal enabledelayedexpansion

  5. set "inputFile=Libraries.Info"
  6. set "outputFile=Libraries.Info.tmp"
  7. set "searchString=FL.Backups"
  8. set "newPath=%localadds%FL.Backups"
  9. if exist %outputFile% del %outputFile%

  10. (for /f "tokens=*" %%a in ('type "%inputFile%"') do (
  11.     set "line=%%a"
  12.     set "modifiedLine="
  13.     set "tempLine="
  14.     for %%b in (!line!) do (
  15.         set "token=%%~b"
  16.         set "temp=!token:%searchString%=!"
  17.         if "!temp!"=="!token!" (
  18.             set "tempLine=!tempLine!%%~b "
  19.         ) else (
  20.             set "tempLine=!tempLine!%newPath% "
  21.         )
  22.     )
  23.     rem Remove any leading and trailing non-alphanumeric characters from the line
  24.     set "tempLine=!tempLine:>*[^A-Za-z0-9]=!"
  25.     set "tempLine=!tempLine:~0,-1!"
  26.     echo !tempLine!
  27. )) > "%outputFile%"

  28. echo "Replacement complete."

  29. endlocal
  30. goto finalOutput
复制代码
这样写可以用,就是蠢了一点,不知道会不会有其他问题

作者: szwp    时间: 2024-4-18 09:07
cii09 发表于 2024-4-18 08:47
这样写可以用,就是蠢了一点,不知道会不会有其他问题

将问题简化,无关的代码就不要发了。

2024-04-17_142249.png (4.53 KB, 下载次数: 58)

2024-04-17_142249.png

作者: cii09    时间: 2024-4-18 09:38
szwp 发表于 2024-4-18 09:07
将问题简化,无关的代码就不要发了。

前两天试了几次没成功。这样写
set "searchString=FL.Backups$"
...
set "b=!a:%searchString%=%newStr%!"
这个没办法生效,不知道是格式转译问题,还是逻辑问题。现在发不了附件,直接贴看起来就一大坨,见谅
作者: junyee    时间: 2024-4-21 08:48
本帖最后由 junyee 于 2024-4-21 08:49 编辑

没有看批处理.

1.  首先, findstr 支持的不是正则, 帮助里描述的是 "通用表达式"

findstr 的用法,隔壁专业论坛有一个帖子:

批处理命令findstr正则表达式的基本用法


2. 排除掉语法逻辑,批处理对一些特殊字符串处理有很多坑的, 如  <>"\=^| 和空格,要特别注意. 还有批处理自身的编码格式,甚至非 \r\n 的换行符都能带来莫名其妙的问题.


作者: junyee    时间: 2024-4-21 08:53
本帖最后由 junyee 于 2024-4-21 08:56 编辑
cii09 发表于 2024-4-18 09:38
前两天试了几次没成功。这样写
set "searchString=FL.Backups$"
...

把发现有疑问处单独拎出来,自己写一个完整的测试脚本.
不要让有心帮忙的人看一堆垃圾代码.人家测试是无偿的帮助,还要给你揣测用意+写测试脚本
?????


  1. @echo off
  2. setlocal enabledelayedexpansion

  3. set a="123456FL.Backups$7890"
  4. set "searchString=FL.Backups$"

  5. set newStr=####
  6. set "b=!a:%searchString%=%newStr%!"

  7. echo %b%
  8. pause
复制代码





作者: junyee    时间: 2024-4-21 08:58
junyee 发表于 2024-4-21 08:53
把发现有疑问处单独拎出来,自己写一个完整的测试脚本.
不要让有心帮忙的人看一堆垃圾代码.人家测试是无 ...

set 不生效的原因是,没有启用变量延迟扩展.
也就是上面第二行.

setlocal enabledelayedexpansion

写起来很长是不是,能不能简化?不能.写着写着就能记住 了.



作者: cii09    时间: 2024-4-21 11:07
本帖最后由 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结尾的行,是不是延迟变量里面不可以这么写,需要怎么修改

作者: szwp    时间: 2024-4-21 11:38
在问findstr还是set?
作者: cii09    时间: 2024-4-21 11:59
szwp 发表于 2024-4-21 11:38
在问findstr还是set?

这两个配合起来跑不通,set里面可以支持$吗
作者: junyee    时间: 2024-4-21 12:02
cii09 发表于 2024-4-21 11:07
顶楼贴的第16行已经启用了延迟变量,因为定位不到故障点,能力不足无法精简问题了。
实在没办法在#9的替 ...

能力不足就更要多学习.
精力不足就出悬赏帖,隔壁论坛有版块.

请用最简练的文字描述问题,并给出测试环境(脚本/文件).


看了下顶楼的第二部分,给出代码如下,下不为例.

  1. @echo off
  2. setlocal enabledelayedexpansion

  3. set "str1=FL.Backups"
  4. set /a cnt=0


  5. for /f "delims=" %%i in (1.txt) do (
  6. call :find_replace "%%~i"  "%str1%"
  7. )


  8. pause&GOTO:EOF



  9. :find_replace
  10. echo %~1|findstr /V "%str1%$" &&goto:EOF
  11. set "str2=%~1"
  12. set /a cnt+=1
  13. set str2=%str2:!str1!=%
  14. echo D:\test%cnt%\%str1%
  15. goto:EOF
复制代码

作者: szwp    时间: 2024-4-21 12:13
cii09 发表于 2024-4-21 11:59
这两个配合起来跑不通,set里面可以支持$吗

仔细看俺回的帖和图,进cmd练
作者: szwp    时间: 2024-4-21 12:14
/E   在一行的结尾配对模
作者: cii09    时间: 2024-4-21 13:28
junyee 发表于 2024-4-21 12:02
能力不足就更要多学习.
精力不足就出悬赏帖,隔壁论坛有版块.

感谢指点!
印象中隔壁有段时间好久都打不开,以为跑路了,之后就没去过。




欢迎光临 无忧启动论坛 (http://bbs.wuyou.net/) Powered by Discuz! X3.3