gpt4 book ai didi

windows - 遍历文件夹并获取命令行输入的文件名

转载 作者:可可西里 更新时间:2023-11-01 10:41:02 46 4
gpt4 key购买 nike

我试图迭代文件夹中的文件,并在do循环中使用另一个批处理文件来处理它们。它可以与echo一起工作,但是当我将变量用作程序的输入时,它就会回显()部分和内部的所有内容。
这就是我要做的。

@echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
for /r %%f in (/folder/*) do (
set name="%%~nf"
echo !name! <--- ok
process.bat !name! <--- echoes () and commands inside this do loop
)
ENDLOCAL

bat只是将文件名的第一个字母大写,并回显以进行调试或确认。

最佳答案

必须使用命令call从批处理文件中调用批处理文件,否则windows命令处理器将继续处理其他批处理文件,而不会返回到初始批处理文件。
另请参见:How to call a batch file that is one level up from the current directory?
请阅读由batch file echo on/off not working properly编写的dbenham上的优秀答案,原因是在第一次执行process.bat后,没有使用命令调用就突然获得由执行以输出的命令。我无法更好地解释在这种情况下会发生什么。
Windows上的目录分隔符是反斜杠字符\,而不是Linux或Mac上的正斜杠/。出于兼容性原因,windows还支持文件/文件夹路径中的/,方法是在访问windows文件系统之前自动将所有/替换为\,但编写良好的脚本使用100%正确的语法,不依赖于其他程序所做的自动更正。/主要用于windows上的命令行开关。
使用/而不是\会导致意外行为。例如,运行包含以下内容的批处理文件:

@echo off
echo Files in directory %SystemRoot:\=/%/:
for %%I in (%SystemRoot:\=/%/*) echo %%I
echo/
pause
echo/
echo Files in directory %SystemRoot%\:
for %%I in (%SystemRoot%\*) echo %%I
echo/
pause

第一种使用 C:/Windows/*作为通配符模式的方法只输出驱动器号+冒号+文件名+文件扩展名的文件名。输出文件名中缺少文件路径 \Windows\。第二个for循环使用 C:\Windows\*作为通配符模式输出完全限定的文件名,即驱动器号+冒号+文件路径+文件名+文件扩展名。
\开头的文件/文件夹路径引用相对于当前驱动器根目录的目录或文件。
Microsoft文档 Naming Files, Paths, and Namespaces对此进行了解释。
看起来 folder是执行的批处理文件目录中的一个子目录。在这种情况下,文件夹路径开头的 /\绝对不正确。可以省略开头的反斜杠,也可以使用 .\在执行批处理文件时引用当前目录中的目录 folder。但是,批处理文件执行的当前目录也可以不同于包含已执行批处理文件的目录,例如,在以管理员身份运行批处理文件时,或在按计划任务运行批处理文件时,或在使用unc访问的网络资源中运行批处理文件时路径。因此,建议显式引用批处理文件目录中的子目录 folder
只要当前分配给循环变量的文件名不需要修改(除了 for的修饰符支持),就不需要延迟环境变量扩展。类似于 set name="%%~nf"的命令行在启用延迟扩展时无法正常工作,并且文件名包含一个或多个 !,因为 cmd.exe将文件名中的感叹号解释为延迟扩展的环境变量引用的开始/结束。
另请参见: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
看起来不需要对非隐藏文件进行递归搜索,因为如果只传递没有路径和文件扩展名的文件名,则不足以获得由其他批处理文件 process.bat处理的正确文件。
因此,整个任务很可能也可以通过以下方式完成:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
for %%I in ("%~dp0folder\*") do call "%~dp0process.bat" "%%~nI"
endlocal

但是,如果另一个批处理文件 process.bat希望在执行 process.bat时传递的文件名(不带文件扩展名和路径)位于当前目录中,则必须首先将此批处理文件目录中的子目录 folder设置为当前目录。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0folder"
for %%I in (*) do call "%~dp0process.bat" "%%~nI"
popd
endlocal

注意:用 %~dp0引用的批处理文件文件夹路径总是以反斜杠结尾。因此,在将此路径字符串与文件/文件夹名连接到避免最后在执行批处理文件时使用完全限定的文件/文件夹名 \\时使用额外的反斜杠,尽管Windows内核也通过删除本案。
为了理解使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页。
call /?
echo /?
endlocal /?
popd /?
pushd /?
set /?
setlocal /?

关于windows - 遍历文件夹并获取命令行输入的文件名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57747732/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com