cii09 发表于 2024-4-16 20:47:29

[初步解决]请问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








2012飘水 发表于 2024-4-16 21:08:58

学习一下看看

ningzhonghui 发表于 2024-4-16 21:18:03

看不懂,等老师来讲解下

wang1126 发表于 2024-4-17 06:39:07

谢谢分享

nathan6498 发表于 2024-4-17 13:06:23

谢谢分享

szwp 发表于 2024-4-17 13:27:27

findstr /?
/E         在一行的结尾配对模式。
$      行位置: 行的终点

是这个意思么?

cii09 发表于 2024-4-17 13:35:49

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:21

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


FINDSTR /n /E .\FL.Backups
试一下

cii09 发表于 2024-4-18 08:47:21

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这样写可以用,就是蠢了一点,不知道会不会有其他问题

szwp 发表于 2024-4-18 09:07:21

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

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

cii09 发表于 2024-4-18 09:38:35

szwp 发表于 2024-4-18 09:07
将问题简化,无关的代码就不要发了。
前两天试了几次没成功。这样写
set "searchString=FL.Backups$"
...
set "b=!a:%searchString%=%newStr%!"
这个没办法生效,不知道是格式转译问题,还是逻辑问题。现在发不了附件,直接贴看起来就一大坨,见谅

junyee 发表于 2024-4-21 08:48:27

本帖最后由 junyee 于 2024-4-21 08:49 编辑

没有看批处理.

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

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

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


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

junyee 发表于 2024-4-21 08:53:51

本帖最后由 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:58:54

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

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

setlocal enabledelayedexpansion

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


cii09 发表于 2024-4-21 11:07:34

本帖最后由 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:35

在问findstr还是set?

cii09 发表于 2024-4-21 11:59:56

szwp 发表于 2024-4-21 11:38
在问findstr还是set?

这两个配合起来跑不通,set里面可以支持$吗

junyee 发表于 2024-4-21 12:02:06

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

szwp 发表于 2024-4-21 12:13:03

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

仔细看俺回的帖和图,进cmd练

szwp 发表于 2024-4-21 12:14:00

/E   在一行的结尾配对模

cii09 发表于 2024-4-21 13:28:23

junyee 发表于 2024-4-21 12:02
能力不足就更要多学习.
精力不足就出悬赏帖,隔壁论坛有版块.



感谢指点!
印象中隔壁有段时间好久都打不开,以为跑路了,之后就没去过。
页: [1]
查看完整版本: [初步解决]请问findstr表达式配合set的通配符引用为什么会无效