@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET "destdir=U:\destdir"
for /f "delims=" %%G in ('dir /b /a-d "%sourcedir%\*.m3u"') do (
REM "%%G" contains the name+extension of each M3U file in turn
for /F "usebackq delims=" %%q in ("%sourcedir%\%%G") do (
rem %%q contains the entire contents of the file "%%G" - each such line is itself a full-filename
for /f "delims=" %%s in ("%%q") do echo %%~nxs
)
)>"%destdir%\%%~nxG"
GOTO :EOF
您将需要更改设置sourcedir以destdir适应您的情况。该清单使用适合我的系统的设置。
在第一行,dir/b输出分配给元变量 %%G。如果遇到适合的目录名称,该/a-d开关将关闭目录名称。*.m3u
"delims="将dir输出行分配给%%G- 整行,除了行之外什么都没有。这些行是扫描目录时遇到的文件的名称。
注意结构for ... do ( ....whatever.... )>"filename"。这意味着将任何输出收集( ....whatever.... )到一个新文件中。(>>代替>将附加到现有文件,或者如果没有现有文件则创建一个新文件......)使用name 和 eX张力命名%%G。如果您想要.txt输出文件而不是.M3u(匹配 中的扩展名%%G),那么您只需使用%%~nG.txt.
现在我们处理每个文件“ %%G”。由于名称可能包含空格,因此usebackq需要使用该选项。同样,delims=将从文件中读取的整行分配给%%q.
文件名也是如此%%q。将for/f其用作文字(由"quoting"它)处理,然后我们可以使用它%%~nxs来“显示” 的“名称和扩展名” %%s。
那么 - 你的版本出了什么问题?
好吧,tokens=*基本上delims=做同样的事情(但前者抑制了像空格这样的前导分隔符)。eol=~会截断dir之前的任何文件名输出~,这可能实际上没有发生 - 这只是一个潜伏的问题。
在循环中,您正在设置remove. 这里有两个小问题。首先,最好使用语法SET "var=value"(其中 value 可能为空;在这种情况下var变为undefined)用于确保分配的值中不包含任何杂散的尾随空格。
其次,更严重的是,当您Remove在下一行中使用时,将使用遇到Remove时的值,for因为您的代码使用%Remove...%. 要按预期使用当前值,您需要打开delayedexpansion(如您所愿)并使用!Remove...!. 即使在那里,您也会尝试将处理后的值分配给result.
使用set "remove=%%G"会更好一些(不是你想要的,文件%%G名也是.m3u如此 - 不是它的内容,但更好)然后你会尝试设置result为the contents of "remove" with all leading characters up to and including the first "\" replaced by *nothing*
因此,如果正在处理的变量的内容C:\Users\username\Music\Ed Sheeran\x (Deluxe Edition)\04 Don't.mp3如您显然预期的那样,那么结果将只是删除C:\.
然后 - echoing%result%将不会echo编辑任何内容,因为在遇到result时没有任何价值for。echo !result!可能工作得更好一些(!因为值已被循环修改)but thenecho with an argument that is resolved to *nothing* reportsecho is off`(或打开,视情况而定),而不是预期的空行。
复杂,是吗?没关系 - 一旦你掌握了它的窍门,批处理就会很有趣。