如何在批处理脚本中找到 m3u 播放列表文件大小?

How to find m3u playlist filesize in batch script?

我正在尝试查找目录中 m3u 播放列表文件的文件大小。我不知道批处理脚本的正确语法,所以下面的代码可能 运行 不正确。

我需要有关此脚本的帮助。

FOR /f %f in ('dir /b') DO {
  SET %filesize% = 0
  FOR /F %i in (%f) DO {
   If %i~1,1% equ ":" AND %i~2,1% equ "\" (%filesize% = %filesize% + %~z1)
  }
 echo %f [%filesize%] & echo. > PlaylistsList.txt
}
  1. 第一行扫描 m3u 文件的基目录,
  2. 第二行将变量文件大小设置为 0,这样它就不会在每个循环中不断添加。
  3. 第三行将每个m3u播放列表文件作为文本文件输入,在另一个循环中处理。
  4. 第四行通过 :\ 比较 2nd3rd 字符来检查文件路径格式是否为 "C:\music\" 格式。然后为在 m3u 播放列表文件中找到的每个文件添加文件大小。
  5. 最后,文件名与文件大小一起被回显。

因此 PlaylistsList.txt 中的输出:

Rock.m3u [900 mb]

Electronic.m3u [500 mb]

Acoustic.m3u [150 mb]

首先,批处理文件中for循环中的变量名必须以2 %开头。因此,在您的变量中插入更多百分号。其次,将您的块放在括号内 (),而不是 {}


另一个问题是您的 set 命令。 set 中的变量名没有被百分号包围,赋值必须紧跟在等号之后,否则你的变量的实际值将包括前面的空格。正确的做法是这样的:SET filesize=0SET "filesize=0"

您还一次又一次地添加第一个参数的文件大小(注意 z1 而不是 zi

%filesize% = %filesize% + %~z1

您必须使用 %~zi 获取列表中文件的大小并将其添加到总和中。但是你不能像上面那样直接做数学。使用 set /a 代替

set /a filesize += %%~zi

并且您读取的 m3u 文件内容不正确。要read a line from a text file使用这种方式

for /F "tokens=*" %%L in (%%f) do [command]

我不明白你的第 4 行。您想要检查该行是否以 C:\music\ 开头,但您却检查第二个字符是否为 : 而第三个字符是否为 \。这有几个问题:

  • IF 不支持 AND
  • 等多个条件
  • 您不能在 for 循环中对变量进行子字符串化,因为它不像普通变量那样被百分号包围。

要子字符串,首先将值赋给一个普通变量:set line=%%L。要检查这两种情况,有几种解决方法 like this,但您的情况只是检查单个字符串,因此您不需要检查单独的字符。如果您想要上述行为,请使用 if "!line:~1,2!"==":\",或使用 if /i "!line:~0,2!"=="C:\music\" 检查您提到的文件夹,使用 /i 进行不区分大小写的检查。 for 循环中的变量必须用 !! 包围,以使其在运行时展开。记得在开头使用setlocal EnableDelayedExpansion

最后你不需要 & echo. 因为 echo 总是在打印后换行。但是你必须使用 >> 来附加输出文件,否则每次你重定向 echo.

时它都会删除旧内容

现在要计算文件大小,您需要自己计算,因为文件大小只是一个数值。请注意,没有名为 mb 的数据大小单位。如果您想要 MiB(Windows 项中的 MB),则除以 1024,然后除以 1000 以获得 MB。

所以脚本应该是这样的

setlocal EnableDelayedExpansion

for /f %%f in ('dir /b') DO (
    set filesize=0
    for /F "tokens=*" %%L in (%%f) do (
        set line=%%L
        if "!line:~1,2!"==":\" set /a filesize += %%~zL
    )
)
set /a filesize /= 1024
echo %%f [%filesize% MB] >> PlaylistsList.txt

奖励:如果需要四舍五入的文件大小结果,请使用

set divisor=1024
set /a filesize = (%filesize% + %divisor%/2) / %divisor%

编辑:

为了适应长文件名,第二个 for 循环应该像这样 usebackq 使用

for /F "usebackq tokens=*" %%L in ('%%f') do (

另一种方法是调用另一个函数来获取文件大小

set line=%%L
CALL :FileSize "%%L"
if "!line:~1,2!"==":\" set /a filesize += %%~zL

:FileSize
SET filesize=%~z1

一个重要的注意事项是 set 中使用的变量是 32 位有符号整数,因此 如果总大小超过 2GB,它将不起作用。

根据 Luu 的回答更正!

setlocal EnableDelayedExpansion

for /f "tokens=* delims=" %%f in ('dir *.m3u /b') DO (
    set filesize=0
    REM set var1="%%f"
    REM echo %var1%
    for /f "useback tokens=* delims=" %%L in ("%%~f") do (
        set line=%%L
        if "!line:~1,2!"==":\" set /a filesize += %%~zL
    )
    REM set /a filesize /= 1024
    echo %%f [!filesize! MB] >> PlaylistsList.txt
)
pause