(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` 是文件还是文件夹? [复制]的主要内容,如果未能解决你的问题,请参考以下文章