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

[文件操作] [已解决]求助批处理双变量同时包含!和%的输出

本帖最后由 kingshui 于 2013-4-24 19:42 编辑

有一test1文件包含以下内容(文件名及路径)
  1. X:\require\https%3A%2F%2Fgithub.com
  2. X:\require\!test.com
复制代码
想要输出成如下(test2)的内容:
  1. "X:\require\https%3A%2F%2Fgithub.com" "\https%3A%2F%2Fgithub.com"
  2. "X:\require\!test.com" "\!test.com"
复制代码
已经作出如下代码:
  1. For /f "delims=" %%i In (test1) Do (
  2. Echo "%%i" "%~nxi">>test2
  3. )
复制代码
想了一些法子,都无法同时支持!和%的输出...
望指点,变量延迟用怕了.
这是完整一点的
  1. :package
  2. if "%~1" NEQ "" (
  3. echo %~1 >>patch
  4. if "%~2" NEQ "" echo %~2 >>patch
  5. if "%~3" NEQ "" echo %~3 >>patch
  6. if "%~4" NEQ "" echo %~4 >>patch
  7. if "%~5" NEQ "" echo %~5 >>patch
  8. if "%~6" NEQ "" echo %~6 >>patch
  9. if "%~7" NEQ "" echo %~7 >>patch
  10. if "%~8" NEQ "" echo %~8 >>patch
  11. if "%~9" NEQ "" echo %~9 >>patch
  12. call :packagemod
  13. )
  14. :packagemod
  15. SETLOCAL ENABLEDELAYEDEXPANSION
  16. set cmdstr=MAKECAB /v3 /D CompressionType=LZX /D CompressionMemory=21 /D MaxDiskSize=CDROM /D Cabinet=On /D Compress=On /D FolderSizeThreshold=5000000 /D DiskDirectoryTemplate="%~dp1." /D CabinetNameTemplate="Por54_Profiles.CAB"
  17. if exist cabstr del cabstr >nul
  18. for /f "delims=" %%i in (patch) do (
  19. set fullname=%%i
  20. set "fullname=!fullname:~0,-1!"
  21. if exist "!fullname!\" (
  22. for /f "delims=" %%a in ('dir "!fullname!" /s /b /a-d') do (
  23. SETLOCAL DISABLEDELAYEDEXPANSION
  24. call set "fn=%%~nxa"
  25. call set "fp1=%%a"
  26. call set "fp=%%~dpa"
  27. SETLOCAL ENABLEDELAYEDEXPANSION
  28. call set "fpr=%~dp0"
  29. call set fp=%%fp:!fpr!=%%
  30. call echo "%%fp1%%" "!fp!%%fn%%">>cabstr
  31. ENDLOCAL
  32. ENDLOCAL
  33. )
  34. ) else (
  35. echo "%%i" "%%~nxi">>cabstr
  36. )
  37. )
  38. %cmdstr% /F cabstr
复制代码
我大概是想疯了....
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

回复 15# kingshui


    括号代表复合语句,预处理时会把 %var% 先解释成字符串,而 !var! 则留到命令实际执行前夕再临时解释,用 call 的目的是避免 %var% 位于复合语句中

TOP

回复 14# Batcher


    多谢您的帮助,看明白了*号了,那么关于小括号的那一个个人理解的说法有解释吗?谢谢。

TOP

回复 13# kingshui


看帮助文档:
Environment variable substitution has been enhanced as follows:

    %PATH:str1=str2%

would expand the PATH environment variable, substituting each occurrence
of "str1" in the expanded result with "str2".  "str2" can be the empty
string to effectively delete all occurrences of "str1" from the expanded
output.  "str1" can begin with an asterisk, in which case it will match
everything from the beginning of the expanded output to the first
occurrence of the remaining portion of str1.
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复 12# CrLf


    非常感谢,已经成功了,关于兄的代码有两处不明白,能否指点下?

1)
  1. (for /f "delims=" %%a in (cabstr) do (
  2.    set "str=%%a"
  3.    call :fun
  4. ))>b.txt
复制代码
此处的call为什么不能以小括号包含的方式来处理?如:
  1. (for /f "delims=" %%a in (cabstr) do (
  2.    set "str=%%a"
  3.    (
  4. set "str=%str:!=|%"
  5. setlocal enabledelayedexpansion
  6. set str="!str!" "!str:*%key%=!"
  7. endlocal&echo %str:|=!%
  8. )
  9. ))>b.txt
复制代码
2)另一个就是在此处
  1. set str="!str!" "!str:*%key%=!"
复制代码
这个"*"星号的作用是什么?如果有资料的话能否提供个链接学习下?
谢谢,真的非常感谢。

TOP

  1. @echo off
  2. set "key=X:\require\test\"
  3. set "key=%key:!=|%"
  4. (for /f "delims=" %%a in (a.txt) do (
  5.    set "str=%%a"
  6.    call :fun
  7. ))>b.txt
  8. pause&exit
  9. :fun
  10. set "str=%str:!=|%"
  11. setlocal enabledelayedexpansion
  12. set str="!str!" "!str:*%key%=!"
  13. endlocal&echo %str:|=!%
复制代码
1

评分人数

TOP

回复 10# kingshui
那4楼代码 5行 这样的意思吗
  1. echo "!str!" "!str:%~dp0=!"
复制代码

TOP

回复 7# terse


    是%~dp0
谢谢。

TOP

回复 8# CrLf


    测试了下。最后的输出!还是转义之后的|并没有再转义回!。

TOP

回复 6# kingshui
  1. @echo off
  2. set "key=X:\require\test\"
  3. set "key=%key:!=|%"
  4. (for /f "delims=" %%a in (a.txt) do (
  5.    set str=%%a
  6.    call set "str=%%str:!=|%%"
  7.    setlocal enabledelayedexpansion
  8.    echo "!str!" "!str:*%key%=!"
  9.    endlocal
  10.    call set "str=%%str:|=!%%"
  11. ))>b.txt
  12. pause
复制代码

TOP

这里的变量是那里来   当前路径吗

TOP

回复 4# CrLf


    非常感谢你的深夜回复,第三方的话是不考虑的了。
  1.     @echo off
  2.     (for /f "delims=" %%a in (a.txt) do (
  3.        set str=%%a
  4.        setlocal enabledelayedexpansion
  5.        echo "!str!" "!str:*:\require\test\=!"
  6.        endlocal
  7.     ))>b.txt
  8.     pause
复制代码
我一直纽结在
  1. echo "!str!" "!str:*:\require\test\=!"
复制代码
这里,如果把*:\require\test\改为变量的话就始终不能同时处理了。实在不行的话就只能处理掉这两个符号了。cab压缩是个麻烦事啊。

TOP

或用第三方 sed:
  1. @sed "s/^.:\\require\\test\\\(.*\)/\x22&\x22 \x22\1\x22/" a.txt>b.txt
复制代码

TOP

  1. @echo off
  2. (for /f "delims=" %%a in (a.txt) do (
  3.    set str=%%a
  4.    setlocal enabledelayedexpansion
  5.    echo "!str!" "!str:*:\require\test\=!"
  6.    endlocal
  7. ))>b.txt
  8. pause
复制代码

TOP

本帖最后由 kingshui 于 2013-4-21 23:09 编辑

回复 2# CrLf


    我晕了...
我弄个简单的路径了...变成这样就不懂了.
  1. X:\require\test\test2\https%3A%2F%2Fgithub.com
  2. X:\require\test\!test.com
复制代码
截取了前面的X:\require\test\
变成这样:
  1. "X:\require\test\test2\https%3A%2F%2Fgithub.com" "test2\https%3A%2F%2Fgithub.com
  2. "X:\require\test\!test.com" "!test.com"
复制代码
代码就不会写了.....

TOP

返回列表