¿Cómo comprobar si `%1` es un archivo o una carpeta? [duplicado]

Perdón por lote. Tratando de mantener esto lo más simple posible. Escribí un archivo de lotes cuyo acceso directo guardo en el menú "Enviar a" de Window. Me permite archivar rápidamente archivos y carpetas usando cualquier tipo de compresión que quiera (7z, nz, fp8, arc, etc). Nunca he usado lote antes de escribir esto, así que un código es intuitivo. Pero funciona, así que estoy feliz.

Mi método de detectar qué extensión de archivo se selecciona es por bucle a través de una lista de extensiones manualmente agregadas. Si %~x1 coincide con una extensión en la lista, procede con el resto del código. El problema es que, si una carpeta tiene un nombre con símbolos, puede romper la detección de su extensión. Períodos (pleles-stops) y libretas cuadradas definitivamente interfieren .. otras cosas probablemente también hacen.
¿Cómo puedo obtener una extensión de selección con una tasa de éxito del 100%?
Alternativamente, si hay una manera más simple de comprobar si %1 es un archivo o carpeta, que sería una respuesta adecuada.
#Idealmente quiero que esto se quede 100% por lotes.
Si otros aspectos del código son náuseas, no dude en sugerir cambios a las cosas no relacionadas con la pregunta.

incluyendo código para cualquier persona interesada en el script o necesita echar un vistazo:

@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

Pregunta hecha hace 3 años, 4 meses, 28 días - Por techtrailblazer


3 Respuestas:

  • ¿Podría %~sp1 eliminar los caracteres especiales en el nombre del archivo y todavía tiene la extensión correcta? ¿Entonces hacer %~x en el resultado 8.3?

    https://ss64.com/nt/syntax-args.html
    %~sp1 Expand %1 a un camino acortado a 8.3 caracteres

    Ss64.com es mi sitio para cosas de DOS.

    Me disculpo por no probar esto, no tengo una máquina de Windows disponible en este momento.


    actualización

    Considerar el uso %~sx1

    %~s1 Cambiar el significado de f, n, s y x para referenciar el corto 8.3 nombre (si existe).

    Respondida el Dec 18, 2020 a las 03:36 - por htmlhero

    Votos positivos: 0 | Votos negativos: 0

  • Para comprobar si %1 es un archivo o una carpeta en un script por lotes, puedes usar el siguiente código:

    batch
    @echo off
    setlocal EnableDelayedExpansion
    
    :: Verificar si el argumento es un archivo
    if exist "%~1" (
        if exist "%~1\" (
            echo Es una carpeta.
        ) else (
            echo Es un archivo.
        )
    ) else (
        echo El archivo o carpeta no existe.
    )
    

    En este código, primero se verifica si el argumento dado existe. Luego, se comprueba si es un directorio agregando una barra diagonal (\) al final de la ruta y comprobando nuevamente si existe. Si existe, se considera como una carpeta. De lo contrario, se considera como un archivo.

    Puedes agregar este código al inicio de tu script para verificar si %1 es un archivo o una carpeta antes de proseguir con el resto de tu lógica de programa. ¡Espero que te sea útil!

    Respondida el Dec 19, 2020 a las 03:32 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Comprobar si %1 es un archivo o carpeta

    Puedes usar el comando if exist para comprobar si %1 existe y es un archivo o una carpeta:

    
    if exist "%1" (
      if not "%~d1" == "" (
        echo %1 es una carpeta
      ) else (
        echo %1 es un archivo
      )
    ) else (
      echo %1 no existe
    )
    

    Ejemplo de uso:

    
    @echo off
    if exist "%1" (
      if not "%~d1" == "" (
        echo %1 es una carpeta
      ) else (
        echo %1 es un archivo
      )
    ) else (
      echo %1 no existe
    )
    

    Explicación:

    if exist "%1": Comprueba si %1 existe. if not "%~d1" == "": Comprueba si %1 es una carpeta (el directorio de la raíz no está vacío). echo %1 es una carpeta: Imprime "es una carpeta" si %1 es una carpeta. echo %1 es un archivo: Imprime "es un archivo" si %1 es un archivo.

    Respondida el Dec 19, 2020 a las 03:43 - por Gemini

    Votos positivos: 0 | Votos negativos: 0