[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
原来兄不在论坛管理群,倒忘了以前在群里是哪几个人讨论过此问题。
当时我用的例子和你这个类似(另外还用了VBS监控进程创建来观察%cmdcmdline%),真是英雄所见略同。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

qzw居然把我那个例子拿出来了
zqz0012005 发表于 2011-4-29 19:39

恕我无知
竟然不知道那段文字引用了你哪个例子

关于等号替换
我认为稳妥的办法还是逐个字符检测
特殊字符可以另行处理
  1. @echo off
  2. set _exp=if "%%a%%"=="%%b%%" echo 2^^3=8^>out.txt
  3. set _exp
  4. set "_exp=%_exp:"="%"
  5. :loop
  6. if "%_exp:~0,1%"=="=" (
  7. set "_exp2=%_exp2%="
  8. ) else (
  9. set "_exp2=%_exp2%%_exp:~0,1%"
  10. )
  11. set "_exp=%_exp:~1%"
  12. if not "%_exp%"=="" goto :loop
  13. set "_exp=%_exp2:"="%"
  14. set _exp2=
  15. set _exp
  16. echo 老实的办法:逐个字符判断是否等号,是则替换,不是则直接连接
  17. pause
复制代码
天的白色影子

TOP

qzw居然把我那个例子拿出来了,这应该是cmd.exe自身的BUG,解析命令行有缺陷。应该无解,除非让微软打补丁。

替换等号那个,无法兼容特殊字符。对特殊字符的处理存在不足是cmd.exe的根本缺陷。只有研究它的源码才知道问题在何处。

PS:最近工作中经常涉及对字符串的解析与处理,发现不少问题,比如内存泄露、踩内存、逻辑问题之类的,这玩意的确很让人头疼。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

本帖最后由 qzwqzw 于 2011-4-29 16:30 编辑
说下,和shell32.dll没关系,明显是cmd的事情。。。
slore 发表于 2011-3-25 17:32

呵呵
这可真是公说公有理婆说婆有理了
cmd怪shell32不把&用引号包裹住再交过来
shell32怪cmd自己不把赤裸的&管教好
一嘴烂账没法说清

不过又回头多想了一下
这个问题仍有探索的余地
余地就在%cmdcmdline%
那里包裹了更多的信息
想办法处理了一下
因为以前很少关注转义字符的处理
费了许多功夫才大致完成
最终的结果是给定的12个特殊文件处理了11个
唯一剩下的一个(abc)&(xyz).cmd
没什么好办法
因为它直接导致批处理无法启动
  1. :: 测试多个怪僻文件名直接拖拽到批处理文件上,批处理是否正确处理这些文件名
  2. @echo off
  3. rem pause
  4. if not [%1]==[] goto :start
  5. echo 正在生成测试文件
  6. echo.>abc.cmd
  7. echo.>"abc xyz.cmd"
  8. echo.>"abc^xyz.cmd"
  9. echo.>"abc&xyz.cmd"
  10. echo.>"abc & xyz.cmd"
  11. echo.>"(abc)(xyz).cmd"
  12. echo.>"(abc) (xyz).cmd"
  13. rem echo.>"(abc)&(xyz).cmd"
  14. echo.>"(abc) & (xyz).cmd"
  15. echo.>"abc;xyz.cmd"
  16. echo.>"abc,xyz.cmd"
  17. echo.>"abc=xyz.cmd"
  18. echo @echo 溢出漏洞存在!^&pause>xyz.cmd
  19. echo 测试文件生成.
  20. goto :eof
  21. :start
  22. echo starting...
  23. set _line="%cmdcmdline:"="%"
  24. set _line=%_line:^=^%
  25. set _line=%_line:&=&%
  26. set _line=%_line:(=(%
  27. set _line=%_line:)=)%
  28. set _line=%_line:,=,%
  29. set _line=%_line:;=;%
  30. set _line=%_line: =□%
  31. rem set _line
  32. rem pause
  33. setlocal EnableDelayedExpansion
  34. for %%f in (%_line:~1,-1%) do set _line2=!_line2!=%%f
  35. endlocal & set _line=%_line2:□= %
  36. set _line=%_line:"="%
  37. set _line=%_line:~9,-1%
  38. rem set _line
  39. rem pause
  40. setlocal EnableDelayedExpansion
  41. for %%f in (%_line%) do (
  42. set _file="%%~f"
  43. set _file=!_file:^=^^!
  44. set _file=!_file:&=^&!
  45. set _file=!_file:(=^(!
  46. set _file=!_file:)=^)!
  47. set _file=!_file:,=,!
  48. set _file=!_file:;=;!
  49. set _file=!_file:===!
  50. if exist !_file! (echo ---!_file!---) else (echo ___"%%~f"____)
  51. )
  52. endlocal
  53. echo 结束
  54. pause
复制代码
另外
转义字符的处理过程中
又遇到了等号的替换问题
顺便提供了一种新思路
  1. @echo off & setlocal EnableDelayedExpansion
  2. set _exp=var=value
  3. set _exp
  4. set _exp=%_exp:===%
  5. set _exp
  6. echo 全角等号可以直接替换
  7. pause
  8. set _exp=var=value
  9. set _exp
  10. for %%f in ("=") do (
  11. call set _exp=!_exp:%%~f=-!
  12. )
  13. set _exp
  14. echo 半角等号不能直接替换
  15. pause
  16. set _exp=var=value
  17. set _exp
  18. set _exp=%_exp: =□%
  19. set _exp=%_exp:;=;%
  20. for %%e in (%_exp%) do set _exp2=!_exp2!=%%e
  21. set _exp=%_exp2:□= %
  22. set _exp=%_exp:;=;%
  23. set _exp=%_exp:~1%
  24. set _exp
  25. echo 转折的办法:把非等号的for分隔符替换掉,再用for遍历被等号分隔的所有串,并且用等号的替换字符连接这些串,最后将其它分隔符恢复,不支持处理连续的等号
  26. pause
复制代码
天的白色影子

TOP

用批处理的办法基本无解

这个问题源于Explorer的拖放扩展程序shell32.dll
注册表路径位于HKEY_CLASSES_ROOT\CLSID\{86C86720-42A0-1069-A2E8-08002B30309D}
因为它没有将“&"视为转义符号
所以不会用引号对将其 ...
qzwqzw 发表于 2010-4-6 11:41



说下,和shell32.dll没关系,明显是cmd的事情。。。

TOP

原帖由 GNU 于 2010-4-11 12:18 发表
我始终认为,批处理就应该是一次双击全部搞定,拖放=蛋疼。


是啊,太蛋疼了,批处理如果要进行要拖放失去了批处理的快捷高效。。。。一点意思都没有。。。
菜鸟学批,一批一大批~~~~~~

TOP

楼上这么麻烦干嘛?一句话的事:
for %%a in (%*) do echo %%~fa

这样说来,难道以后拖放只能用set /p了吗?
set /p n=&&for /f %%a in ("%n:"=%") do echo %%~fa

TOP

晕掉,以前长篇大论都没达到效果,以下几个字就解决了!~
因为用的是FOR,不支持那些变态文件,但基本上能满足一般使用了,比如拖入MP3播放。
  1. @echo off
  2. for /f "tokens=*" %%a in ("%*") do (
  3. for %%i in (%%a) do if exist %%i echo %%i
  4. )
  5. pause
复制代码

TOP

经过一个下午的努力,终于有了结果,效率不是很高,但还是基本能够实现目标。第一次来挑战区,请多多指教。
  1. echo.>abc.txt
  2. echo.>"abc xyz.txt"
  3. echo.>"abc^xyz.txt"
  4. echo.>"abc&xyz.txt"
  5. echo.>"abc & xyz.txt"
  6. echo.>"(abc)(xyz).txt"
  7. echo.>"(abc) (xyz).txt"
  8. echo.>"(abc)&(xyz).txt"
  9. echo.>"(abc) & (xyz).txt"
  10. echo.>"abc;xyz.txt"
  11. echo.>"abc,xyz.txt"
  12. echo.>"abc=xyz.txt"
复制代码
可以同时拖拉多个文件到批处理中,最后获取这几个文件的完全合格文件名。
文件名含有空格的也可以实现。
但文件名中含有(.)与(&)的,后缀名非三位(如.db、html)的无法读取——需要重新设置。
不处理文件夹。

已经支持的后缀名有:txt;doc;exe;rar;mp3;jpg;wma;bat,其它格式需补充。
可能与 “echo %*”有关,重定向时自动放到“%USERPROFILE% ”中去了,只好用 “>>%~dp0”。

由于用了两对重复的FOR,特别是设置“hzm”的FOR,导致速度下降。
应该也支持从单个文本内容中提取路径名。方法是将“~dp0_2tyxs.txt”改为该文本名称。
其它方面有待完善。

  1. @echo off&setlocal enabledelayedexpansion
  2. echo %*>>"%~dp0_test.txt"
  3. echo.>"%~dp0_test2.txt"
  4. echo.>"%~dp0_results.txt"
  5. for /f "usebackq tokens=*" %%i in ("%~dp0_test.txt") do (
  6. set var=%%i
  7. for /l %%a in (0,1,1000) do (
  8. set /a ddl=%%a-1
  9. set str2=!var:~%%a,2!
  10. if "!str2!"==":\" call echo %%var:~!ddl!,1%%!var:~%%a,1000!>>"%~dp0_test1.txt"
  11. )
  12. )
  13. for %%l in (txt;doc;exe;rar;mp3;jpg;wma;bat;htm;pdf;ppt) do (
  14. set hzm=%%l
  15. for /f "usebackq tokens=*"  %%i in ("%~dp0_test1.txt") do (
  16. set var=%%i
  17. for /l %%a in (0,1,1000) do (
  18. set /a ddf=%%a+4
  19. set str=!var:~%%a,4!
  20. if "!str!"==".!hzm!" echo !var:~0,%%a!.!hzm!>>"%~dp0_test2.txt"
  21. )
  22. )
  23. for /f "usebackq tokens=1,2,3,4 delims=." %%a in ("%~dp0_test2.txt") do (
  24. set vara=%%a
  25. set varb=%%b
  26. if /i "!varb:~0,3!"=="!hzm!" echo !vara!.!varb:~0,3!>>"%~dp0_test3.txt"
  27. )
  28. )
  29. for /f "usebackq delims=" %%a in (`sort "%~dp0_test3.txt"`) do (
  30. if not %%a equ !b! echo %%a>>"%~dp0_results.txt"
  31. set b=%%a)
  32. del "%~dp0_test.txt"
  33. del "%~dp0_test1.txt"
  34. del "%~dp0_test3.txt"
  35. del "%~dp0_test2.txt"
  36. start "" "%~dp0_results.txt"
  37. EXIT
复制代码

[ 本帖最后由 cjiabing 于 2010-8-21 10:42 编辑 ]

TOP

我始终认为,批处理就应该是一次双击全部搞定,拖放=蛋疼。

TOP

回复 16楼 的帖子

呵呵 namejm说的没错,而且我发现c语言也有这功能,有意思。
我的原意是将多个文件放入一个文件夹,然后将文件夹拖到cmd窗口,然后用dir %1得到所要的文件路径,避免了显示如abc&xyz.txt这样名字的文件的路径时出错
@echo off
set /p=>hlw1.txt<nul

TOP

原帖由 todayambition 于 2010-4-10 10:33 发表
@echo off
echo %*
pause
中用%*接收全部参数都没有得到abc&xyz.txt,应该是不行的
不过,把要此批处理显示路径的所有文件放到一个文件夹(如:d:\temp\)下,再dir d:\temp\*.txt /b
就得到了所要的路径

  把多个文件拖曳到cmd窗口来处理,其实是添加了人机互动的环节,能带来更大的灵活性,这是用 dir 命令所无法企及的。
尺有所短寸有所长,学好批处理没商量;
考虑问题复杂化,解决问题简洁化。

心在天山,身老沧州。

TOP

发觉大家,都有点太为难 set/p 命令了
  

           哈哈, 不过 也只有这样才能长知识长见识○( ̄﹏ ̄)○
    ╭╩═╮
╭╯G O ╠ 雁过留声
╰⊙═⊙╯

TOP

@echo off
echo %*
pause
中用%*接收全部参数都没有得到abc&xyz.txt,应该是不行的
不过,把要此批处理显示路径的所有文件放到一个文件夹(如:d:\temp\)下,再dir d:\temp\*.txt /b
就得到了所要的路径

TOP

原帖由 zqz0012005 于 2010-4-9 21:09 发表
应该算是大家都知道的老经验了吧,对于%x参数引用较保险的做法是"%~x"
怎么又重新讨论了呢?

在 D 盘根目录新建一个文本文档,命名为 "R&B.txt" ,也就是创建一个文本文档 “D:\R&B.txt” ,
现在讨论的问题是把它拖到一个内容为

@echo off
echo %*
pause


的批处理文件上,怎样能使批处理能显示 D:\R&B.txt

TOP

返回列表