Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 多次求和迭代后的负数_Batch File_Cmd - Fatal编程技术网

Batch file 多次求和迭代后的负数

Batch file 多次求和迭代后的负数,batch-file,cmd,Batch File,Cmd,因此,我决定批量制作适合某张dvd的电影列表。 问题是它有时返回负数作为文件的大小 @set @x=0 /* @echo off @set _thisbatchscript="%~f0" @setlocal enabledelayedexpansion @set max=8525510083 @set "parentfolder=%__CD__%" @set flenght=1 @for /r . %%g in (*.*) do ( @call :gera "%%g" @set "var=%%

因此,我决定批量制作适合某张dvd的电影列表。
问题是它有时返回负数作为文件的大小

@set @x=0 /*
@echo off
@set _thisbatchscript="%~f0"
@setlocal enabledelayedexpansion
@set max=8525510083
@set "parentfolder=%__CD__%"

@set flenght=1
@for /r . %%g in (*.*) do (
@call :gera "%%g"
@set "var=%%g"
@set var=!var:%parentfolder%=!
@set fname[!flenght!]=!var!
@set /a flenght=!flenght!+1
)
@set /a flenght=!flenght!-1

@set movielgt=1
@for /l %%a in (1,1,!flenght!) do (
if !fext[%%a]!==.avi (
@set movienm[!movielgt!]=!fname[%%a]!
@set moviesz[!movielgt!]=!fsize[%%a]!
@set ftemp=!fname[%%a]!
@set ftemp=!ftemp:.avi=!
@set movienoext[!movielgt!]=!ftemp!
@set /a movielgt=!movielgt!+1
)
)
@set /a movielgt=!movielgt!-1

@set subtitlelgt=1
@for /l %%a in (1,1,!flenght!) do (
@if !fext[%%a]!==.srt (
@set subtitlenm[!subtitlelgt!]=!fname[%%a]!
@set subtitlesz[!subtitlelgt!]=!fsize[%%a]!
@set ftemp=!fname[%%a]!
@set ftemp=!ftemp:.srt=!
@set subtitlenoext[!subtitlelgt!]=!ftemp!
@set /a subtitlelgt=!subtitlelgt!+1
)
)
@set /a subtitlelgt=!subtitlelgt!-1

@for /l %%a in (1,1,!movielgt!) do (
@for /l %%b in (1,1,!subtitlelgt!) do (
@if !movienoext[%%a]!==!subtitlenoext[%%b]! (
@set /a moviesz[%%a]=!moviesz[%%a]!+!subtitlesz[%%b]!
)
)
)

set resultlgt=0
for /l %%a in (1,1,!movielgt!) do (
if !moviesz[%%a]! LEQ %max% (
set _tempresultsz=0
set _tempresultnm=
set tamanho=
for /l %%b in (%%a,1,!movielgt!) do (
set /a tamanho+=!moviesz[%%b]!
if !tamanho! LEQ %max% (
set /a _tempresultsz+=!moviesz[%%b]!
set _tempresultnm=!_tempresultnm! !movienm[%%b]!
call :resultpush  "!_tempresultnm!" !_tempresultsz!
)
)
)
)


echo tamanho;arquivos
for /l %%a in (1,1,!resultlgt!) do (
echo !result[%%a]sz!;!result[%%a]nm!
) 


:gera
@set fsize[!flenght!]=%~z1
@set fext[!flenght!]=%~x1
@goto :EOF

:resultpush
@set /a resultlgt+=1
for /f "tokens=* delims= " %%a in ("%~1") do set str=%%a
@set result[!resultlgt!]nm=%str%
REM for /f "delims=" %%i in ('cscript //Nologo //E:jscript %_thisbatchscript% %2') do set _tamanho=%%i
@set result[!resultlgt!]sz=%2
@goto :EOF
REM start of javascript (not in use(too slow to run on evey interation)) 
goto:EOF */
var Size=WScript.Arguments(0);
var result=Size+" Bytes"
if(Size>=1024){
    result=(Size/1024)+" KB";
}
if(Size>=1048576){
    result=(Size/1048576)+" MB";
}
if(Size>=1073741824){
    result=(Size/1073741824)+" GB";
}
if(Size>=1099511627776){
    result=(Size/1099511627776)+" TB";
}
WSH.echo(result);
是的,这就是密码
基本上,它从调用的路径中获取文件夹和子文件夹中的文件的完整列表,并对其进行迭代以查找.avi和.srt文件。它将.avi文件的大小与具有相同文件夹路径和文件名的.str文件的大小相加,最后,它再次迭代计算可能适合dvd的文件列表

是的,正如一些黑暗的东西所暗示的,你的头撞到了32位整数的极限。您的JScript混合代码可以处理更大的值,最高可达2 TB(64位)

如果您稍微更改一下混合格式,就可以有多个JScript作业(即使您愿意)。下面是一个演示:


Echo((WSH.Arguments(0)*1)+(WSH.Arguments(1)*1));
变量大小=WSH.Arguments(0)*1,
idx=0;
而(size>1024&&++idx)size/=1024;
Echo(size.toFixed(1)+['B','KB','MB','GB','TB'][idx]);

顺便说一句,您可以在脚本中改进一些其他方面。首先,并非批处理脚本中的所有内容都必须左对齐。这也会起作用:

用于/f%%I英寸(
'cscript//nologo“%~f0?.wsf”“%~1”“%~2”//job:add'
)做(
设置“%~3=%%I”
)
其次,由于在脚本顶部使用了
@echo off
,因此不必在每个命令前面加上
@
符号。这就是回声关闭的要点

最后,当使用
set/A
时,不必使用周围的百分比或感叹号来引用等式中的值。因此,以下三个命令中的每一个都执行完全相同的操作:

set/a flenght=!弗莱特!+1.
设置/a flenght=flenght+1
设置/a flenght+=1

您的代码有一个基本错误,但它不是其他地方描述的32位整数溢出

当文件记录在所有类型的光盘(包括DVD)中时,数据总是使用整个磁盘扇区写入,或者更准确地说,使用由整数个磁盘扇区组成的整个群集(数据块)写入。根据“一个DVD数据块中有16个扇区。一个扇区由2048字节(仅数据)构成,因此一个DVD数据块大小为2048*16字节(=32768字节)”。标准DVD的总容量为2295104个磁盘扇区,相当于2295104*2048=4700372992字节(俗称“4.7GB”);然而,数据块中DVD的总容量为2295104/16=143444。写入磁盘上的每个文件都会占用一个32 KB的整数数据块,因此每个文件(以数据块为单位,而不是以字节为单位)的大小是从初始的143444个可用数据块(而不是4700372992个可用字节)减少的量。如果您使用不同容量的DVD,只需相应地调整数值即可

此(正确)方法还允许使用SET/A命令的32位整数限制完成所有算术运算

@echo off
setlocal EnableDelayedExpansion

set /A max=143444, clusterSize=32*1024, allMovies=0

set "flenght=0"
for /R %%g in (*.avi) do (
   set /A "lastFit=flenght, lastFitP1=lastFit+1, flenght+=1, thisMovie=(%%~Zg-1)/clusterSize+1"
   set "fname[!flenght!]=%%~Fg"
   if exist "%%~PNg.srt" for %%s in ("%%~PNg.srt") do (
      set /A "flenght+=1, thisMovie+=(%%~Zs-1)/clusterSize+1"
      set "fname[!flenght!]=%%~Fs"
   )
   set /A "allMovies+=thisMovie"
   if !allMovies! gtr %max% (
      echo/
      echo These files fits in one DVD:
      for /L %%i in (1,1,!lastFit!) do echo !fname[%%i]!

      set "i=0"
      for /L %%i in (!lastFitP1!,1,!flenght!) do (
         set /A i+=1
         set "fname[!i!]=!fname[%%i]!"
      )
      set /A flenght=i, allMovies=thisMovie
   )
)
if %flenght% gtr 0 (
   echo/
   echo These files fits in one DVD:
   for /L %%i in (1,1,%flenght%) do echo !fname[%%i]!
)

这是一个整数溢出错误;batch只能使用32位整数进行数学运算,因此可以使用的最大数字是2147483647。这是我仅有的两次建议您使用PowerShell的其中一次。非常感谢您,我正在疯狂地试图找出我的错误。。。非常感谢。因此,即使我将所有逻辑部分移植到jscript并从那里进行计算,如果我得到一个超过2147483647字节的文件,它也会变成负数?不一定;批处理将所有变量视为字符串,除非使用
set/a
。任何数学运算都必须在jScript中完成,但如果只是显示一个值,batch可以处理它。太棒了!现在就开始吧。再次谢谢你!我不知道cscript上有没有像乔布斯这样的东西,它看起来真的很棒。我几乎在每一行上都加上了@,因为如果我遇到错误,我会把回音注释掉,以找出错误发生的地方。set/a提示非常好,将更改这里的所有其他bat文件,非常感谢!天哪。。。这真是令人印象深刻,你应该看起来像我做的奇美拉,实际上我打开了另一个问题,因为它也不完美。非常感谢你,我实际上会改变我接受的答案,因为你不仅回答了这个问题,而且还提供了一个完全可以满足我需要的代码。非常感谢!