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

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

心在天山,身老沧州。

TOP

回复 16楼 的帖子

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

TOP

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

TOP

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

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

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

@echo off&setlocal enabledelayedexpansion
echo %*>>"%~dp0_test.txt"
echo.>"%~dp0_test2.txt"
echo.>"%~dp0_results.txt"
for /f "usebackq tokens=*" %%i in ("%~dp0_test.txt") do (
set var=%%i
for /l %%a in (0,1,1000) do (
set /a ddl=%%a-1
set str2=!var:~%%a,2!
if "!str2!"==":\" call echo %%var:~!ddl!,1%%!var:~%%a,1000!>>"%~dp0_test1.txt"
)
)
for %%l in (txt;doc;exe;rar;mp3;jpg;wma;bat;htm;pdf;ppt) do (
set hzm=%%l
for /f "usebackq tokens=*"  %%i in ("%~dp0_test1.txt") do (
set var=%%i
for /l %%a in (0,1,1000) do (
set /a ddf=%%a+4
set str=!var:~%%a,4!
if "!str!"==".!hzm!" echo !var:~0,%%a!.!hzm!>>"%~dp0_test2.txt"
)
)
for /f "usebackq tokens=1,2,3,4 delims=." %%a in ("%~dp0_test2.txt") do (
set vara=%%a
set varb=%%b
if /i "!varb:~0,3!"=="!hzm!" echo !vara!.!varb:~0,3!>>"%~dp0_test3.txt"
)
)
for /f "usebackq delims=" %%a in (`sort "%~dp0_test3.txt"`) do (
if not %%a equ !b! echo %%a>>"%~dp0_results.txt"
set b=%%a)
del "%~dp0_test.txt"
del "%~dp0_test1.txt"
del "%~dp0_test3.txt"
del "%~dp0_test2.txt"
start "" "%~dp0_results.txt"
EXITCOPY

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

TOP

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

TOP

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

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

TOP

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


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

TOP

用批处理的办法基本无解

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



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

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
没什么好办法
因为它直接导致批处理无法启动
:: 测试多个怪僻文件名直接拖拽到批处理文件上,批处理是否正确处理这些文件名
@echo off
rem pause
if not [%1]==[] goto :start
echo 正在生成测试文件
echo.>abc.cmd
echo.>"abc xyz.cmd"
echo.>"abc^xyz.cmd"
echo.>"abc&xyz.cmd"
echo.>"abc & xyz.cmd"
echo.>"(abc)(xyz).cmd"
echo.>"(abc) (xyz).cmd"
rem echo.>"(abc)&(xyz).cmd"
echo.>"(abc) & (xyz).cmd"
echo.>"abc;xyz.cmd"
echo.>"abc,xyz.cmd"
echo.>"abc=xyz.cmd"
echo @echo 溢出漏洞存在!^&pause>xyz.cmd
echo 测试文件生成.
goto :eof
:start
echo starting...
set _line="%cmdcmdline:"="%"
set _line=%_line:^=^%
set _line=%_line:&=&%
set _line=%_line:(=(%
set _line=%_line:)=)%
set _line=%_line:,=,%
set _line=%_line:;=;%
set _line=%_line: =□%
rem set _line
rem pause
setlocal EnableDelayedExpansion
for %%f in (%_line:~1,-1%) do set _line2=!_line2!%%f
endlocal & set _line=%_line2:□= %
set _line=%_line:"="%
set _line=%_line:~9,-1%
rem set _line
rem pause
setlocal EnableDelayedExpansion
for %%f in (%_line%) do (
set _file="%%~f"
set _file=!_file:^=^^!
set _file=!_file:&=^&!
set _file=!_file:(=^(!
set _file=!_file:)=^)!
set _file=!_file:,=,!
set _file=!_file:;=;!
set _file=!_file:===!
if exist !_file! (echo ---!_file!---) else (echo ___"%%~f"____)
)
endlocal
echo 结束
pauseCOPY
另外
转义字符的处理过程中
又遇到了等号的替换问题
顺便提供了一种新思路
@echo off & setlocal EnableDelayedExpansion
set _exp=var=value
set _exp
set _exp=%_exp:===%
set _exp
echo 全角等号可以直接替换
pause
set _exp=var=value
set _exp
for %%f in ("=") do (
call set _exp=!_exp:%%~f=-!
)
set _exp
echo 半角等号不能直接替换
pause
set _exp=var=value
set _exp
set _exp=%_exp: =□%
set _exp=%_exp:;=;%
for %%e in (%_exp%) do set _exp2=!_exp2!%%e
set _exp=%_exp2:□= %
set _exp=%_exp:;=;%
set _exp=%_exp:~1%
set _exp
echo 转折的办法:把非等号的for分隔符替换掉,再用for遍历被等号分隔的所有串,并且用等号的替换字符连接这些串,最后将其它分隔符恢复,不支持处理连续的等号
pauseCOPY
天的白色影子

TOP

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

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

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

TOP

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

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

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

TOP

原来兄不在论坛管理群,倒忘了以前在群里是哪几个人讨论过此问题。
当时我用的例子和你这个类似(另外还用了VBS监控进程创建来观察%cmdcmdline%),真是英雄所见略同。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

本帖最后由 techon 于 2011-5-10 01:45 编辑

原来是这样的。。。只要路径或文件名中有空格 就会加上引号从而处理任何文件名,
路径和文件名都没有空格,但是有特殊符号时 如 & ^ % 等 则会出现错误。。。

怪不得我在桌面上找了一堆文件都没问题呢

TOP

为什么不试试这个:
(abc)&(xyz).txt

TOP

本帖最后由 techon 于 2011-5-10 01:51 编辑

这个cmd  shell 不给力 改天试试 PowerShell

TOP

返回列表