批处理文件以删除绝对路径并仅在多个文件中保留文件名

Batch file to delete absolute paths and leave only filename in multiple files

我有点头疼了。我正在尝试编写一个 .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) Don't.mp3
    C:\Users\username\Music\Eric Church\Chief (2011)-eric_church-homeboy.mp3

期望的输出:

    Dr. Dre & Snoop Doggy Dog - Ain't Nothin But A G-Thang.mp3
    x (Deluxe Edition) 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

您需要更改 sourcedirdestdir 的设置以适合您的情况。该列表使用适合我的系统的设置。

在第一行中,dir/b 输出被分配给 元变量 %%G。如果遇到符合 *.m3u 的目录名称,/a-d 开关会关闭目录名称。

"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.[=71 的“名称和扩展名” =]

那么 - 你的版本出了什么问题?

嗯,tokens=*delims= 本质上做同样的事情(但前者像空格一样抑制 leading-delimiters)。 eol=~ 会在 ~ 之前截断 dir 中的任何 filename-output,这可能实际上并没有发生 - 这只是一个潜在的问题。

在循环中,您正在设置 remove。这里有两个小问题。首先,最好使用语法 SET "var=value"(其中值可能为空;在这种情况下 var 变为 undefined)用于确保任何杂散尾随空格不包括在分配的值中。

其次,更严重的是,当您在下一行中使用 Remove 时,将使用遇到 forRemove 的值,因为您的代码使用 %Remove...%。要按预期使用 current 值,您需要打开 delayedexpansion(如您所愿)并使用 !Remove...!。即使在那里,您也会尝试将 processed-value 分配给 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) Don't.mp3,那么结果将只是删除 C:\.

然后 - echoing %result%echoed nothing 因为 resultfor遇到了。 echo !result! 可能工作得更好一些(! 因为值已被循环修改)but thenechowith an argument that is resolved to *nothing* reportsecho 已关闭`(或打开,视情况而定) be),而不是预期的空行。

复杂吗?没关系 - 一旦掌握了批处理就很有趣。