Board logo

标题: [文件操作] [已解决]求助批处理双变量同时包含!和%的输出 [打印本页]

作者: kingshui    时间: 2013-4-21 21:33     标题: [已解决]求助批处理双变量同时包含!和%的输出

本帖最后由 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
复制代码
我大概是想疯了....
作者: CrLf    时间: 2013-4-21 22:15

  1. @echo off
  2. For /f "delims=" %%i In (test1) Do (
  3. Echo "%%i" "%%~nxi">>test2
  4. )
  5. pause
复制代码

作者: kingshui    时间: 2013-4-21 23:02

本帖最后由 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"
复制代码
代码就不会写了.....
作者: CrLf    时间: 2013-4-22 00:01

  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
复制代码

作者: CrLf    时间: 2013-4-22 00:01

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

作者: kingshui    时间: 2013-4-22 01:00

回复 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压缩是个麻烦事啊。
作者: terse    时间: 2013-4-22 09:39

这里的变量是那里来   当前路径吗
作者: CrLf    时间: 2013-4-22 17:06

回复 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
复制代码

作者: kingshui    时间: 2013-4-24 01:06

回复 8# CrLf


    测试了下。最后的输出!还是转义之后的|并没有再转义回!。
作者: kingshui    时间: 2013-4-24 01:08

回复 7# terse


    是%~dp0
谢谢。
作者: terse    时间: 2013-4-24 01:56

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

作者: CrLf    时间: 2013-4-24 01:58

  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:|=!%
复制代码

作者: kingshui    时间: 2013-4-24 19:41

回复 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%=!"
复制代码
这个"*"星号的作用是什么?如果有资料的话能否提供个链接学习下?
谢谢,真的非常感谢。
作者: Batcher    时间: 2013-4-24 20:28

回复 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.

作者: kingshui    时间: 2013-4-24 23:07

回复 14# Batcher


    多谢您的帮助,看明白了*号了,那么关于小括号的那一个个人理解的说法有解释吗?谢谢。
作者: CrLf    时间: 2013-4-25 15:31

回复 15# kingshui


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




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2