我正在尝试转换多行脚本
@echo off
for /f "eol=: delims=" %%D in ('dir /b /s /ad *^|sort /r') do (
pushd "%%D"
for %%F in (*) do move "%%F" "..\%%~nxD - %%F" >nul
popd
rd /s /q "%%D"
)
exit
将其添加到一行中,以便将其注册为上下文菜单项。据我理解,等效的单行命令如下:
@echo off && for /f "eol=: delims=" %%D in ('dir /b /s /ad *^|sort /r') do (pushd "%%D" && for %%F in (*) do move "%%F" "..\%%~nxD - %%F" >nul && popd && rd /s /q "%%D") && exit
...但它产生的结果与原始脚本不同。
用 & 替换 && 会产生第三个不同的结果,但据我所知,在这种情况下我仍然需要 &&。
我可能做错了什么?
答案1
事实证明这for … do
是“贪婪的”。(我不记得以前知道这一点,而且它似乎在 中没有突出的记录for /?
。)
我的意思是:
考虑脚本cow1.bat
:
@echo off
for %%a in (how now brown) do echo %%a
echo cow
非常简单。运行时,它输出
how
now
brown
cow
正如我们所猜测的。
考虑脚本cow2.bat
:
@echo off
for %%a in (how now brown) do echo %%a & echo cow
相同,只是第 2 行和第 3 行已连接,并以 分隔&
。猜猜是什么!?运行时,它会输出
how
cow
now
cow
brown
cow
它被解读为
@echo off
for %%a in (how now brown) do (echo %%a & echo cow)
(更改&
为&&
没有任何效果。)令我更惊讶的是,
@echo off
for %%a in (how now brown) do (echo %%a) & echo cow
还功能与 相同cow2
。我不得不使用
@echo off
(for %%a in (how now brown) do echo %%a) & echo cow
获得原始的cow1
行为。
这对 OP 有何影响?
for %%F in (*) do move "%%F" "..\%%~nxD - %%F" >nul && popd && rd /s /q "%%D"
类似于cow2
:如果(我们刚刚进入的%%D
目录)是,则上述代码段执行以下操作:pushd
beatles
move "george" "..\beatles - george" >nul && popd && rd /s /q "beatles"
move "john" "..\beatles - john" >nul && popd && rd /s /q "beatles"
move "paul" "..\beatles - paul" >nul && popd && rd /s /q "beatles"
move "ringo" "..\beatles - ringo" >nul && popd && rd /s /q "beatles"
(为清晰起见添加了空格)。因此,它会移动第一个文件(george
),然后popd
移出beatles
目录并将其删除,而其他文件则由 roomba 来获取。
建议(TL;DR)
尝试
对于/f“eol =:delims =”%%D在('dir / b / s / ad * ^ | sort / r')中执行(pushd“%%D”&&(对于 (*) 中的 %%F,请移动 "%%F" "..\%%~nxD - %%F" >nul)&& popd && rd /s /q "%%D") ↑ ↑
琐碎问题:
为什么我们需要子命令*
中的dir /b /s /ad *
?