问题描述
我在这里头晕。我正在尝试编写一个.bat文件,该文件将遍历多个.m3u播放列表文件中的每一行,以删除路径并仅保留文件名。
示例输入:
C:\Users\username\Music\Dr. Dre\Dr. Dre & Snoop Doggy Dog - Ain't Nothin But A G-Thang.mp3
C:\Users\username\Music\Ed Sheeran\x (Deluxe Edition)\04 Don't.mp3
C:\Users\username\Music\Eric Church\Chief (2011)\06-eric_church-homeboy.mp3
所需的输出:
Dr. Dre & Snoop Doggy Dog - Ain't Nothin But A G-Thang.mp3
x (Deluxe Edition)\04 Don't.mp3
06-eric_church-homeboy.mp3
我搜索过高和低,没有运气获得期望的输出。我也没有足够的经验来简化此过程。在我多次失败的尝试中,到目前为止,这是我想到的:
@echo off
setlocal enableDelayedExpansion
for /f "tokens=* delims= eol=~" %%G in ('dir /b "C:\Users\username\Documents\Playlists\*.m3u"') do (
SET Remove=*
SET Result=%remove:*\=% )
ECHO %result%
我尝试使用的方法是删除每一行并删除\
符号之前(包括该符号)的所有内容。到目前为止,我已经能够顺利完成脚本的运行,但是实际上并没有做任何事情。
任何帮助将不胜感激。预先谢谢你。
解决方法
@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
和e {{1 }} X
的张力。如果您希望使用%%G
而不是.txt
(匹配.M3u
中的扩展名)的输出文件,则只需使用%%G
。
现在,我们处理每个文件“ %%~nG.txt
”。由于名称可能包含空格,因此需要使用%%G
选项。同样,usebackq
将从文件读取的整个行分配给delims=
。
因此%%q
是文件名。使用%%q
作为文字(通过for/f
处理),然后我们可以使用"quoting"
“显示” %%~nxs
的“名称和扩展名”。
那么-您的版本出了什么问题?
好吧,%%s
和tokens=*
本质上是做相同的事情(但是前者禁止使用前导定界符,例如空格)。 delims=
会在eol=~
之前截断dir
的任何来自~
的文件名输出,这实际上可能没有发生-这只是一个潜伏的问题。
在循环中,您正在设置remove
。这里有两个小问题。首先,最好使用语法SET "var=value"
(其中值可能为空;在这种情况下var
变为 undefined )可确保不将任何结尾的空格分配的值。
第二,更重要的是,当您在下一行中使用Remove
时,将使用遇到Remove
时的for
值,因为您的代码使用了{ {1}}。要按预期使用 current 值,需要打开%Remove...%
(如您所愿)并使用delayedexpansion
。即使在那儿,您也尝试将处理后的值分配给!Remove...!
。
使用result
会更好一些(不是您想要的,因为set "remove=%%G"
是%%G
文件的名称-不是内容,而是更好),然后您d尝试将.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
都没有{em> ,因为%result%
在echo
出现时没有任何价值。遇到。 result
的效果可能更好一些(for
,因为该值已被循环修改)echo !result!
echo !
echo关闭(或视情况打开)是),而不是预期的空行。
复杂吗?没关系-一旦掌握了批处理功能就很有趣。