(Batch) 如何判断 `%1` 是文件还是文件夹? [复制]

Posted

技术标签:

【中文标题】(Batch) 如何判断 `%1` 是文件还是文件夹? [复制]【英文标题】:(Batch) How to check if `%1` is a file or a folder? [duplicate] 【发布时间】:2020-12-18 03:27:10 【问题描述】:

抱歉批量处理。尽量保持简单。 我写了一个批处理文件,它的快捷方式存储在 Window 的“发送到”菜单中。它允许我使用我想要的任何压缩类型(7z、nz、fp8、arc 等)非常快速地归档文件和文件夹。在写这篇文章之前我从未使用过批处理,所以我的一些代码不直观。不过它有效,所以我很高兴。 :^)

我检测所选文件扩展名的方法是遍历手动添加的扩展名列表。如果 %~x1 与列表中的扩展匹配,则继续执行其余代码。问题是,如果文件夹的名称带有符号,它可能会破坏对其扩展名的检测。句号(句号)和方括号肯定会干扰..其他事情可能也会这样做。 如何以 100% 的成功率获得选择的扩展名? 或者,如果有更简单的方法来检查 %1 是文件还是文件夹,那将是一个合适的答案。 **理想情况下,我希望保持 100% 批次。 如果代码的其他方面令人作呕,请随时建议对与问题无关的内容进行更改。

包括对脚本感兴趣或需要查看的任何人的代码:

@echo off
setlocal EnableDelayedExpansion EnableExtensions
set sizebefore=0
set sizeafter=0
set nl=^&echo.
set "ext=nz"
set barline=---------------------------------------------------------------
::gets date+time (UTC) in order to give archives a unique name
for /f %%Y in ('wmic path win32_utctime get /format:list ^| findstr "="') do set %%Y
set today=%Year%%Month%%Day%
set tempname=%ext%TEMP%today%%Hour%%Minute%%Second%
for %%v in (".7z" ".ahk" ".aiff" ".aif" ".au" ".arc" ".avi" ".avif" ".bak" ".bat" ".bin" ".class" ".cfg" ".config" ".cpp" ".csv" ".cue" ".dat" ".dbf" ".dif" ".dll" ".doc" ".docx" ".eps" ".exe" ".fbt" ".fm3" ".fth" ".fp8" ".fpl" ".gif" ".gz" ".hqx" ".htm" ".html" ".ico" ".ini" ".inf" ".iso" ".ipynb" ".java" ".jpg" ".jpeg" ".js" ".json" ".log" ".m3u" ".m4a" ".m4v" ".mac" ".map" ".mdb" ".mid" ".midi" ".mkv" ".mov" ".mp3" ".mp4" ".msc" ".msi" ".mtb" ".mtw" ".nz" ".osz" ".otf" ".p65" ".pak" ".pdb" ".pdf" ".peace" ".png" ".ppt" ".pptx" ".psd" ".psp" ".py" ".qt" ".qxd" ".ra" ".rar" ".reg" ".resbackup" ".rmf" ".rtf" ".sfx" ".sit" ".sty" ".t65" ".tar" ".tar.gz" ".tdf" ".tex" ".tif" ".ts" ".txt" ".wav" ".webm" ".webp" ".wk3" ".wks" ".wpd" ".wg5" ".xls" ".xlsx" ".xml" ".zip") do (
    if /i "%~x1"=="%%~v" (
        echo File extension identified, %~x1%nl%
          if "%~x1"==".%ext%" cd "%~dp1" && nz x "%1" && ping -n 11 localhost >nul && exit
        set "archivename=%~n1-%today%"
        goto :loc_notfolder
    )
)
    ::error check. some names conflict with %~nx1 and produce a strange value.
    ::if an error occurs (ignoring unknown extensions), remove symbols from selection name
if not exist "%~dp1/%~nx1/" (
    echo Failed to identify selection.%nl%Please add the file extension to the list.%nl%
    goto :loc_info
) else (
    set "archivename=%~nx1-%today%"
    goto :loc_folder
)

::~~archiving files~~
::takes selected files, moves them into unique temp folder,
::archives that folder, then deletes it.
:loc_notfolder
for %%q in (%*) do set /a sizebefore+=%%~zq
echo Archiving as files%nl%%barline%
mkdir %~dp1%tempname% 2> NUL
for %%i in (%*) do xcopy "%%i*" "%~dp1%tempname%\"
cd "%~dp1%tempname%/"
echo Temp folder creation successful%nl%%barline%
nz a -r -cf -cc -m4g "%~dp1%tempname%.%ext%" "%~dp1%tempname%"
if exist "%~dp1%tempname%.%ext%" (
  cd "%~dp1%"
  echo %barline%%nl%Compression successful%nl%Deleting temp folder...%nl%
  rmdir /s /q "%~dp1%tempname%"
  goto :loc_rename
) else (
  goto ::loc_info
)

::~~archiving folder~~
::simple recursive method. no temp files/folders
:loc_folder
::loop to get size of folder. sometimes fails. whatever
set target=%~1
for /f "tokens=3,5" %%a in ('
  dir /a:d /s /w /-c "%target%"
  ^| findstr /b /l /c:"  "
') do if "%%b"=="" set sizebefore=%%c

echo No files selected.%nl%%nl%Archiving as folder%nl%%barline%
cd "%~dp1/%~nx1"
nz a -r -cf -cc -m4g "%~dp1%tempname%.%ext%" "%~dp1%~nx1"
goto :loc_rename



:loc_rename
::storing size of the new archive
for %%g in ("%~dp1%tempname%.%ext%") do set sizeafter=%%~zg

::check if archive already exists. yes=>skip renaming loop
if not exist "%~dp1%archivename%.%ext%" (
  ren "%~dp1/%tempname%.%ext%" "%archivename%.%ext%"
  goto :loc_end
)

::loop to generate an archive that doesn't already exist
set "ncount=1"
:loc_loop
if exist "%~dp1/%archivename%_%ncount%.%ext%" (
  set /a ncount+=1
  goto :loc_loop
)
::attaching value to the desired archive name
set archivename=%archivename%_%ncount%
ren "%~dp1/%tempname%.%ext%" "%archivename%.%ext%"


:loc_end
echo %nl%%nl%%barline%
echo File: %archivename%.%ext%
echo Path: %~dp1%archivename%.%ext%
echo Before: %sizebefore%B
echo After: %sizeafter%B
echo %barline%%nl%

ping -n 11 localhost >nul
exit

::redirect here to check for path problems
:loc_info
echo "~dp0" %~dp0%nl%"~dp1" %~dp1%nl%"~dp2" %~dp2%nl%"~dp3" %~dp3%nl% "~p0" %~p0%nl% "~p1" %~p1%nl% "~p2" %~p2%nl% "~p3" %~p3%nl% "~n0" %~n0%nl% "~n1" %~n1%nl% "~n2" %~n2%nl% "~x0" %~x0%nl% "~x1" %~x1%nl% "~x2" %~x2%nl% "~x3" %~x3%nl%"~nx1" %~nx1%nl%"~nx2" %~nx2%nl%"~nx3" %~nx3%nl%"~fs0" %~fs0%nl%"~fs1" %~fs1%nl%"~fs2" %~fs2%nl%"~fs3" %~fs3%nl% "~f0" %~f0%nl% "~f1" %~f1%nl% "~f2" %~f2%nl% "~f3" %~f3%nl%"~fp0" %~fp0%nl%"~fp1" %~fp1%nl%"~fp2" %~fp2%nl%"~pn0" %~pn0%nl%"~pn1" %~pn1%nl%"~pn2" %~pn2%nl%"~pn3" %~pn3%nl%
pause
exit

【问题讨论】:

暂时将您的脚本内容更改为 1. @echo off, 2. setlocal EnableDelayedExpansion EnableExtensions, 3. @ 987654326@, 4. pause, 5. exit.然后以相同的方式使用它,使用相同的工作文件和有问题的文件,并记下它向您显示的输出。希望这能让您深入了解通过“发送至”过程实际传递给脚本的内容。 在写作的大部分时间里,由于事情经常发生故障,我留下了回声。我本可以发布一个调试版本,但如果无法识别文件扩展名,当前状态下的代码会将用户发送到底部的loc_rename。它在解析已知文件扩展名列表后立即执行此检查。当扩展被认为是未知的时,%~x1 可以返回类似.backup 的值,如果%~1.../***.2020.backup/ 经过进一步测试,我注意到这只发生在文件夹中。这是有道理的,因为文件总是以其关联的扩展名结尾。 Here's what it returns 尝试归档 Desktop\test[test].test.test.whatever\ 时。这是一个被标记为未知文件的文件夹,因为%~x1 返回.whatever 这使我的帖子标题有点误导,因为现在它是与文件夹相关的问题;文件似乎没问题。 显然您需要更改您的批处理文件,以便它确定输入是文件还是目录,然后根据需要为每个创建相关条件。由于该输入是通过“发送到”菜单发送的,因此它应该始终存在,因此它的目录属性 (或缺少它) 可用于帮助做出该决定。 检查文件夹确实要容易得多...不知道为什么我如此重视文件检测。谢谢。我会用修改后的代码更新帖子。 【参考方案1】:

%~sp1 是否会删除文件名中的特殊字符而仍然具有正确的扩展名?那么对 8.3 的结果做 %~x 呢?

https://ss64.com/nt/syntax-args.html %~sp1 将 %1 扩展为缩短为 8.3 个字符的路径

Ss64.com 是我的 DOS 网站。

我很抱歉没有对此进行测试,我目前没有可用的 Windows 机器。


更新

考虑使用 %~sx1

%~s1 更改 f、n、s 和 x 的含义以引用 Short 8.3 名称(如果存在)。

【讨论】:

以上是关于(Batch) 如何判断 `%1` 是文件还是文件夹? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Qt中如何判断文件是照片还是视频?

c#中如何判断一个路径是目录还是文件

php如何判断一个是文件还是文件夹

C++ 如何判断路径是文件还是目录

批处理batch查询目录下文件中的特定字符串

linux如何判断网络是百兆还是千兆