¿Hay alguna manera en un script por lotes de Windows para devolver una ruta absoluta desde un valor que contiene un nombre de archivo y / o ruta relativa?
Dado:
"..\"
"..\somefile.txt"
Necesito la ruta absoluta relativa al archivo por lotes.
Ejemplo:
- "somefile.txt" se encuentra en "C: \ Foo \"
- "test.bat" se encuentra en "C: \ Foo \ Bar".
- El usuario abre una ventana de comando en "C: \ Foo" y llama
Bar\test.bat ..\somefile.txt - En el archivo por lotes "C: \ Foo \ somefile.txt" se derivaría de
%1
windows
batch-file
relative-path
absolute-path
Nathan Taylor
fuente
fuente

realpathpara una normalización de ruta sólida.SET FilePath=%CD%\%1para que sea asíC:\Foo\Bar\..\..\some\other\dir\file.txt. Los programas parecen entender un camino tan complicado.Respuestas:
En los archivos por lotes, como en los programas C estándar, el argumento 0 contiene la ruta al script que se está ejecutando actualmente. Puede usar
%~dp0para obtener solo la parte de ruta del argumento 0 (que es el script actual): esta ruta siempre es una ruta totalmente calificada.También puede obtener la ruta totalmente calificada de su primer argumento utilizando
%~f1, pero esto proporciona una ruta de acuerdo con el directorio de trabajo actual, que obviamente no es lo que desea.Personalmente, a menudo uso el
%~dp0%~1idioma en mi archivo por lotes, que interpreta el primer argumento relativo a la ruta del lote en ejecución. Sin embargo, tiene una deficiencia: falla miserablemente si el primer argumento está completamente calificado.Si necesita admitir rutas relativas y absolutas, puede utilizar la solución de Frédéric Ménez : cambiar temporalmente el directorio de trabajo actual.
Aquí hay un ejemplo que demostrará cada una de estas técnicas:
Si guarda esto como c: \ temp \ example.bat y lo ejecuta desde c: \ Users \ Public como
c: \ Users \ Public> \ temp \ example.bat .. \ windows
... observará el siguiente resultado:
la documentación para el conjunto de modificadores permitidos en un argumento por lotes se puede encontrar aquí: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/call
fuente
%0y de la%1misma manera:%~dpnx0para la ruta totalmente calificada + nombre del archivo por lotes en sí,%~dpnx1para la ruta totalmente calificada + nombre de su primer argumento [si ese es un nombre de archivo en absoluto]. (Pero, ¿cómo demonios nombraría un archivo en una unidad diferente si no proporcionara esa información de ruta completa en la línea de comandos de todos modos?)d:\foo\..\bar\xyz.txttodavía se puede normalizar. Recomiendo usar este enfoque con la respuesta de @ axel-heider a continuación (usando una subrutina por lotes, luego puede hacerlo en cualquier variable, no solo en una variable numerada).Me encontré con una necesidad similar esta mañana: cómo convertir una ruta relativa en una ruta absoluta dentro de un script de comando de Windows.
Lo siguiente hizo el truco:
fuente
pushd .previene este problema.La mayoría de estas respuestas parecen locas por complicadas y súper defectuosas, aquí está la mía: funciona en cualquier variable de entorno, no
%CD%oPUSHD/POPDofor /fsin sentido, simplemente funciones de lote antiguas. - El directorio y el archivo ni siquiera tienen que existir.fuente
%~f1es la abreviatura de, por%~dpfn1lo tanto, siéntase libre de usar%~f1en su lugar. 🙂 - en el formato largo~significa eliminar las comillas,dsignifica unidad,psignifica ruta,nsolo sería nombre de archivo sin extensión, perofnsignifica nombre de archivo con extensión. el1significa el primer argumento. - (Creo que este formato es anterior a Windows 7.)Sin tener que tener otro archivo por lotes para pasar argumentos (y usar los operadores de argumentos), puede usar
FOR /F:donde
iin%%~fies la variable definida en/F %%i. p.ej. si cambiaste eso,/F %%aentonces la última parte sería%%~fa.Para hacer lo mismo en el símbolo del sistema (y no en un archivo por lotes), reemplace
%%con%...fuente
cdcomando no cambia necesariamente la%CD%variable de entorno (por ejemplo, si usted está en la unidadD:y la ruta de destino está enC:)cd /D D:\on.other.driveFOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fifallará si..\relativePathcontiene espaciosfor /?sugiere usar letras mayúsculas para nombres de variables, para evitar confusión con los parámetros de sustitución/Fno funcionará en rutas que no existen, y resolverá los caracteres comodín. Si quieres eso, genial, pero si quieres la funcionalidad de/F, entonces solo necesitas usar latokenspalabra clave:FOR /F "tokens=*" %%I IN ("..\relative Path\*") DO echo absolute path: %%~fIEsto es para ayudar a llenar los vacíos en la respuesta de Adrien Plisson (que debe ser votado tan pronto como lo edite ;-):
Uno puede manejar
%0y%1asimismo:%~dpnx0para una unidad totalmente calificada + ruta + nombre + extensión del lote por sí mismo,%~f0también es suficiente;%~dpnx1para una unidad completa + ruta + nombre + extensión de su primer argumento [si es un nombre de archivo],%~f1también es suficiente;%~f1funcionará independientemente de cómo especificó su primer argumento: con rutas relativas o con rutas absolutas (si no especifica la extensión del archivo al nombrar%1, no se agregará, incluso si usa%~dpnx1).Pero, ¿cómo demonios nombraría un archivo en una unidad diferente de todos modos si no proporcionara esa información de ruta completa en la línea de comandos en primer lugar?
Sin embargo,
%~p0,%~n0,%~nx0y%~x0puede ser útil, si está interesado en la trayectoria (sin letraUnidad), nombre de archivo (sin extensión), nombre completo del archivo con la extensión o sólo la extensión del nombre de archivo. Pero tenga en cuenta, while%~p1y%~n1trabajará para encontrar la ruta o el nombre del primer argumento,%~nx1y%~x1no agregará + mostrará la extensión, a menos que ya lo haya usado en la línea de comandos.fuente
%~dpnx1es que proporciona la ruta completa del argumento en relación con el directorio actual , mientras que el OP desea la ruta relativa al directorio donde reside el archivo por lotes .%~dpnx1da la ruta totalmente calificada del primer argumento. No es relativo en absoluto, y tampoco es relativo al directorio actual. Eldes para la unidad,pes para la ruta,nes para el nombre de archivo sin sufijo,xes para el sufijo,1es para el primer argumento. - Y la pregunta de Nathan fue: "¿Hay alguna forma de devolver una ruta absoluta desde un valor que contenga un nombre de archivo y / o una ruta relativa?"También puede usar funciones por lotes para esto:
fuente
Pequeña mejora a la excelente solución de BrainSlugs83 . Generalizado para permitir nombrar la variable de entorno de salida en la llamada.
Si se ejecuta desde la
C:\projectsalida es:fuente
No he visto muchas soluciones a este problema. Algunas soluciones utilizan el recorrido del directorio mediante CD y otras utilizan funciones por lotes. Mi preferencia personal ha sido para las funciones por lotes y, en particular, la función MakeAbsolute según lo dispuesto por DosTips.
La función tiene algunos beneficios reales, principalmente porque no cambia su directorio de trabajo actual y, en segundo lugar, que las rutas que se evalúan ni siquiera tienen que existir. Puede encontrar algunos consejos útiles sobre cómo usar la función aquí también.
Aquí hay un script de ejemplo y sus resultados:
Y la salida:
Espero que esto ayude ... Seguro que me ayudó :) PD Gracias de nuevo a DosTips! ¡Tú Molas!
fuente
Puedes concatenarlos.
parece extraño con \ .. \ en el medio de su camino pero funciona. No hay necesidad de hacer nada loco :)
fuente
echo %~dp0..\SomeFile.txtEn su ejemplo, desde Bar \ test.bat, DIR / B / S .. \ somefile.txt devolvería la ruta completa.
fuente
PowerShell es bastante común en estos días, así que lo uso a menudo como una forma rápida de invocar C # ya que tiene funciones para casi todo:
Es un poco lento, pero la funcionalidad obtenida es difícil de superar a menos que no se recurra a un lenguaje de script real.
fuente
La solución de stijn funciona con subcarpetas debajo
C:\Program Files (86)\,fuente
Archivos Ver todas las otras respuestas
Directorios
Con
..ser su ruta relativa, y suponiendo que usted está actualmente enD:\Projects\EditorProject:cd .. & cd & cd EditorProject(la ruta relativa)devuelve la ruta absoluta, por ejemplo
D:\Projectsfuente
fuente