tag subdirectorios secundario redirigir puede pudo primario normales lista files crear and windows batch-file cmd

subdirectorios - Lote de Windows: repite la cadena de la carpeta y analiza el nombre de la última carpeta



tag files and folders (12)

Esto es lo que tuvimos al final (un poco más crudo y solo puede llegar tan profundo :)

@echo off for /f "tokens=1-10 delims=/" %%A in (''echo %~p0'') do ( if NOT .%%A==. set new=%%A if NOT .%%B==. set new=%%B if NOT .%%C==. set new=%%C if NOT .%%D==. set new=%%D if NOT .%%E==. set new=%%E if NOT .%%F==. set new=%%F if NOT .%%G==. set new=%%G if NOT .%%H==. set new=%%H if NOT .%%I==. set new=%%I if NOT .%%J==. set new=%%J ) @echo %new%

Necesito tomar el nombre de la carpeta de un archivo por lotes actualmente en ejecución. He estado intentando recorrer el directorio actual usando la siguiente sintaxis (que en este momento está mal):

set mydir = %~p0 for /F "delims=/" %i IN (%mydir%) DO @echo %i

Un par de problemas en los que parece que no puedo pasar el valor de la variable ''mydir'' como cadena de búsqueda. Parece funcionar solo si paso comandos; Tengo la sintaxis incorrecta y no puedo entender por qué.

Mi idea era recorrer la cadena de carpetas con un delimitador ''/', pero esto también está causando problemas. Si configuro una variable en cada ciclo, el último conjunto de valores será el nombre de la carpeta actual. Por ejemplo, dada la siguiente ruta:

C: / Carpeta1 / Carpeta2 / Carpeta3 / Archivo.bat

Esperaría analizar el valor ''Folder3''.

Necesito analizar ese valor ya que su nombre será parte de otra carpeta que voy a crear más abajo en el archivo por lotes.

Muchas gracias si alguien puede ayudar. Puedo estar ladrando el árbol equivocado por completo por lo que cualquier otro enfoque sería muy recibido también.


Leve alteración para si alguna de las carpetas tiene espacios en sus nombres - reemplace el espacio a '':'' antes y después de la operación:

set mydir="%~p0" set mydir=%mydir:/=;% set mydir=%mydir: =:% for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i goto :EOF :LAST_FOLDER if "%1"=="" ( set LAST=%LAST::= % goto :EOF ) set LAST=%1 SHIFT goto :LAST_FOLDER


En los archivos de proceso por lotes en el comando FOR, deberá anteponer% cualquiera que tenga un% extra (por ejemplo, %% lo que sea).

''echo% ~ p0'' imprimirá el directorio actual del archivo por lotes.


Estabas muy cerca de esto :) Esto debería funcionar:

@echo OFF set mydir="%~p0" SET mydir=%mydir:/=;% for /F "tokens=* delims=;" %%i IN (%mydir%) DO call :LAST_FOLDER %%i goto :EOF :LAST_FOLDER if "%1"=="" ( @echo %LAST% goto :EOF ) set LAST=%1 SHIFT goto :LAST_FOLDER

Por algún motivo, al comando for no le gusta ''/' como delimitador, así que convertí todo ''/' a '';'' primero ( SET mydir=%mydir:/=;% )


No sé si es la versión de Windows en la que estoy (win2k3), pero el bucle FOR no me proporciona nada útil para tratar de iterar a través de una sola cadena. De acuerdo con mi observación (y la información FOR /?) Obtienes una iteración por cada línea de entrada a FOR, y no hay forma de cambiar esto para iterar dentro de una línea. Puede dividirse en varios tokens para una línea determinada, pero es solo una invocación del cuerpo de bucle FOR.

Creo que el enfoque CALL: LABEL en estas respuestas hace un gran trabajo. Algo que no sabía hasta que miré esto fue ese ";" y "," son reconocidos como separadores de argumentos. Entonces, una vez que reemplazas las barras invertidas con punto y coma, puedes llamar a tu etiqueta e iterar con SHIFT.

Así que trabajando sobre lo publicado por otros aquí, tengo la siguiente solución. En lugar de tomar el último nombre de la carpeta, en realidad quería encontrar todo hasta algún nombre de directorio conocido ... esto es lo que se implementa a continuación.

@echo off if "%1"=="" goto :USAGE set FULLPATH=%~f1 set STOPDIR=%2 set PATHROOT= :: Replace backslashes with semicolons set FULLPATH=%FULLPATH:/=;% :: Iterate through path (the semicolons cause each dir name to be a new argument) call :LOOP %FULLPATH% goto :EOF :LOOP ::Exit loop if reached the end of the path, or the stop dir if "%1"=="" (goto :EOF) if "%1"=="%STOPDIR%" (goto :EOF) ::If this is the first segment of the path, set value directly. Else append. if not defined PATHROOT (set PATHROOT=%1) else (set PATHROOT=%PATHROOT%/%1) ::shift the arguments - the next path segment becomes %i SHIFT goto :LOOP :USAGE echo Usage: echo %~0 ^<full path to parse^> ^<dir name to stop at^> echo E.g. for a command: echo %~0 c:/root1/child1/child2 child2 echo The value of c:/root1/child1 would be assigned to env variable PATHROOT


Esta pregunta es un poco vieja, pero he buscado una solución más de una vez, así que aquí te presento una idea completamente nueva que acabo de armar.

El truco es que tomamos la ruta deseada, realizamos una copia de seguridad de un nivel para crear una máscara de carpeta para la sustitución y luego reemplazamos la máscara de la carpeta con nada.

Para probarlo, simplemente copie y pegue en un script de comando (.cmd) en cualquier directorio, luego ejecútelo. Escupirá solo el directorio más profundo en el que te encuentras actualmente.

Notas:

  • Reemplace% ~ dp0 con la ruta que desee (tal como está, devolverá la carpeta más profunda desde la que se ejecuta el archivo por lotes. Esto no es lo mismo que% cd%).
  • Al especificar la variable ''pathtofind'', asegúrese de que no haya comillas, por ejemplo, c: / alguna ruta y no "c: / alguna ruta".
  • La idea original para enmascarar carpetas es mía
  • Los espacios en el camino no son un problema
  • La profundidad de la carpeta no es un problema
  • Fue posible gracias al genio de esta sugerencia de scripts por lotes http://www.dostips.com/DtCodeBatchFiles.php#Batch.FindAndReplace

¡Espero que esto ayude a alguien más!

Gracias,

John D

@echo off set pathtofind=%~dp0 if not exist %pathtofind% echo Path does not exist&pause>nul&goto :eof cd /d %pathtofind% set path1=%cd% cd .. set path2=%cd% call set "path3=%%path1:%path2%/=%%" echo %path3% pause>nul


Desafortunadamente, esto está funcionando muy bien solo cuando se pone algo de profundidad pero tiene problemas para estar en la cima de la montaña ... Poner este programa en "C: / Windows", por ejemplo, resultará en ... "C: / Windows" , no se esperaba "Windows". Sigue siendo un gran trabajo, y aún se puede reparar el daño. Mi acercamiento:

@echo off set pathtofind=%~dp0 if not exist %pathtofind% echo Path does not exist&pause>nul&goto :eof cd /d %pathtofind% set path1=%cd% cd .. set path2=%cd% set path4=%~dp1 call set "path3=%%path1:%path2%/=%%" call set "path5=%%path3:%path4%*/=%%" echo %path5% pause>nul

Y está funcionando bien para mí ahora, gracias por la idea, estaba buscando algo así por un tiempo.

jeth


Chicos Sheesh, qué desastre. Esto es bastante fácil, y es más rápido hacer esto en la memoria sin CD.

Esto obtiene los dos últimos directorios de una ruta. Modifíquelo según sea necesario para obtener los últimos tokens de cualquier línea. Mi código original en el que basé esto tiene más complejidad para mis propios fines.

Fyi, esto probablemente no permite caminos con signos de exclamación ya que estoy usando enabledelayedexpansion, pero eso podría ser arreglado.

Tampoco funcionará en una raíz de unidad simple. Esto podría evitarse de varias maneras. Verifique con qué finaliza la ruta de entrada, o un contador, o modificando el token y verificando el comportamiento, etc.

@echo off&setlocal enableextensions,enabledelayedexpansion call :l_truncpath "C:/Windows/temp" ---------- :l_truncpath set "_pathtail=%~1" :l_truncpathloop for /f "delims=/ tokens=1*" %%x in ("!_pathtail!") do ( if "%%y"=="" ( set "_result=!_path!/!_pathtail!" echo:!_result! exit/b ) set "_path=%%x" set "_pathtail=%%y" ) goto l_truncpathloop


Después de luchar con algunas de estas sugerencias, encontré un trazador de líneas 1 utilizado con éxito (en Windows 2008)

for %%a in (!FullPath!) do set LastFolder=%%~nxa


3 líneas de script obtienen el resultado ...

Se encontraron 2 formas adicionales de lograr el objetivo y, a diferencia de las otras respuestas a esta pregunta, no requiere "funciones" por lotes, no hay expansión retardada y tampoco tiene la limitación que la respuesta de Tim Peel tiene con la profundidad del directorio:

@echo off SET CDIR=%~p0 SET CDIR=%CDIR:~1,-1% SET CDIR=%CDIR:/=,% SET CDIR=%CDIR: =#% FOR %%a IN (%CDIR%) DO SET "CNAME=%%a" ECHO Current directory path: %CDIR% SET CNAME=%CNAME:#= % ECHO Current directory name: %CNAME% pause

REVISIÓN: después de mi nueva revisión, aquí hay un resultado de ejemplo:

Current directory path: Documents#and#Settings,username,.sqldeveloper,tmp,my_folder,MY.again Current directory name: MY.again Press any key to continue . . .

Esto significa que el script no maneja ''#'' o '','' en el nombre de una carpeta, pero se puede ajustar para hacerlo.

ADDENDUM: Después de preguntarle a alguien en el foro dostips , encontró una manera aún más fácil de hacerlo:

@echo off SET "CDIR=%~dp0" :: for loop requires removing trailing backslash from %~dp0 output SET "CDIR=%CDIR:~0,-1%" FOR %%i IN ("%CDIR%") DO SET "PARENTFOLDERNAME=%%~nxi" ECHO Parent folder: %PARENTFOLDERNAME% ECHO Full path: %~dp0 pause>nul


Para volver al tema del cartel original:

Por ejemplo, dada la siguiente ruta: C: / Folder1 / Folder2 / Folder3 / Archive.bat Esperaría analizar el valor ''Folder3''.

La solución simple para eso es:

for /D %%I in ("C:/Folder1/Folder2/Folder3/Archive.bat/..") do echo parentdir=%%~nxI

dará ''Folder3''. El archivo / ruta no necesita existir. Por supuesto, ... para el padre padre del padre, o ...... para el anterior que (y así sucesivamente) también funciona.


Encontré este hilo viejo cuando buscaba el último segmento del directorio actual. Las respuestas de los escritores anteriores me llevan a lo siguiente:

FOR /D %%I IN ("%CD%") DO SET _LAST_SEGMENT_=%%~nxI ECHO Last segment = "%_LAST_SEGMENT_%"

Como se explicó anteriormente, no olvide poner comillas alrededor de las rutas de acceso creadas con% _LAST_SEGMENT_% (tal como lo hice con% CD% en mi ejemplo).

Espero que esto ayude a alguien...