如何在自定义目录列表中右对齐文件大小的输出?

问题描述 投票:0回答:1

我正在尝试使用

for
循环批量制作自定义目录列表。

这是代码:

for /F "tokens=* UseBackQ" %%g IN (`dir /b %2`) do (   
    echo  ^| %%~ag %%~tg %%~zg %%~nxg && echo  ^|
)

%2
E:\
时的输出为:

 | d---------- 2022-08-19 02:14 PM 0 AppTemp
 |
 | --a-------- 2022-08-06 11:40 PM 971 learned.py
 |
 | --a-------- 2022-08-19 05:00 PM 4269 main.cmd
 |

我希望文件大小是这样的:

 | d---------- 2022-08-19 02:14 PM    0 AppTemp
 |
 | --a-------- 2022-08-06 11:40 PM  971 learned.py
 |
 | --a-------- 2022-08-19 05:00 PM 4269 main.cmd
 |

我怎样才能做到这样?

batch-file windows-11
1个回答
-1
投票

可以使用以下稍微注释的批处理文件代码:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem Make the directory passed as second argument the current directory
rem checking if a second, non-empty argument string is passed at all to
rem the batch file and with checking if that is really a directory name.

set "RestoreCurrentDirectory="
if "%~2" == "" (
    echo No directory specified as second argument, listing the directory:
    echo "%CD%"
    echo(
) else pushd "%~2" && set "RestoreCurrentDirectory=1" || (
    echo "%~2" is not a valid directory.
    echo(
    exit /B 1
)

rem Get the file size of the largest file in the current directory
rem assigned to environment variable with the name LeadingSpaces.

set "LeadingSpaces="
for /F "eol=| delims=" %%I in ('dir /A-D /B /O-S 2^>nul') do (
    set "LeadingSpaces=%%~zI"
    if defined LeadingSpaces goto GetSpaces
)
set "LeadingSpaces= "
set "NumberSpaces=1"
goto OutputFileNames

rem Replace all digits in file size of largest file by spaces. The string
rem value of the environment variable LeadingSpaces has exactly the same
rem number of spaces as the file size of the largest file in the current
rem directory has as string. Next determine the number of spaces using code
rem from https://www.dostips.com/DtTipsStringOperations.php#Function.strLen

:GetSpaces
setlocal EnableDelayedExpansion
for %%I in (0 1 2 3 4 5 6 7 8 9) do set "LeadingSpaces=!LeadingSpaces:%%I= !"
set "TempString=#%LeadingSpaces%"
set "NumberSpaces=0"
for /L %%I in (12,-1,0) do (
    set /A "NumberSpaces|=1<<%%I"
    for %%J in (!NumberSpaces!) do if "!TempString:~%%J,1!" == "" set /A "NumberSpaces&=~1<<%%I"
)
endlocal & set "LeadingSpaces=%LeadingSpaces%" & set "NumberSpaces=%NumberSpaces%"

rem List all files in the specified directory with right aligned file size
rem with the definition of environment variable FileSize with the leading
rem spaces on which the real file size is appended and output only the last
rem NumberSpaces characters of the file size string with spaces at beginning.

:OutputFileNames
for /F "eol=| delims=" %%I in ('dir /A-D /B 2^>nul') do (
    set "Attributes= | %%~aI"
    set "FileTime=%%~tI"
    set "FileSize=%LeadingSpaces%%%~zI"
    set "FileName=%%~nxI"
    setlocal EnableDelayedExpansion
    echo !Attributes! !FileTime! !FileSize:~-%NumberSpaces%! !FileName!& echo  ^|
    endlocal
)

if defined RestoreCurrentDirectory popd
endlocal

注意:

与命令

DIR

 相比,Windows 命令处理器 
cmd.exe
 无法通过 
%%~aI
 获取文件属性、通过 
%%~tI
 获取上次修改时间以及通过 
%%~zI 获取完全拒绝共享访问的文件的文件大小cmd.exe
,直接从文件系统获取数据。

如果调用此批处理文件时第二个参数为

%SystemDrive%\

,并且系统驱动器的根目录仅包含
hiberfil.sys
pagefile.sys
两个文件,则批处理文件的输出为:

| hiberfil.sys | | pagefile.sys |

hiberfil.sys

pagefile.sys
的文件属性隐藏和系统无关。共享冲突是导致无法获取这两个文件的所有数据进行输出的原因。

运行

DIR 并解析其输出可能会更好,但是 DIR 输出的日期/时间格式取决于为当前用户帐户配置的区域/国家,这使得很可能无法编写代码适用于所有 Windows 计算机的批处理文件。

要了解所使用的命令及其工作原理,请打开

命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。

  • dir /?
    
    
  • echo /?
    
    
  • endlocal /?
    
    
  • exit /?
    
    
  • for /?
    
    
  • if /?
    
    
  • popd /?
    
    
  • pushd /?
    
    
  • rem /?
    
    
  • set /?
    
    
  • setlocal /?
    
    
阅读有关

使用命令重定向运算符的 Microsoft 文档,了解 2>nul

 的说明。重定向运算符 
>
 必须在 
FOR
 命令行上使用脱字符号 
^ 进行转义,以便在 Windows 命令解释器在执行命令 FOR(执行嵌入的 dir
 命令行)之前处理此命令行时将其解释为文字字符使用在后台启动的单独命令进程。

另请参阅

使用 Windows 批处理文件的单行多个命令,了解无条件命令运算符 &

 以及条件命令运算符 
&&
||
 的说明。

© www.soinside.com 2019 - 2024. All rights reserved.