@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.... )
到一个新文件中。(>>
代替>
将附加到现有文件,或者如果没有现有文件则创建一个新文件......)使用n
ame 和 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:\
.
然后 - echo
ing%result%
将不会echo
编辑任何内容,因为在遇到result
时没有任何价值for
。echo !result!
可能工作得更好一些(!
因为值已被循环修改)but then
echo with an argument that is resolved to *nothing* reports
echo is off`(或打开,视情况而定),而不是预期的空行。
复杂,是吗?没关系 - 一旦你掌握了它的窍门,批处理就会很有趣。