¿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
realpath
para una normalización de ruta sólida.SET FilePath=%CD%\%1
para 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
%~dp0
para 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%~1
idioma 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
%0
y de la%1
misma manera:%~dpnx0
para la ruta totalmente calificada + nombre del archivo por lotes en sí,%~dpnx1
para 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.txt
todaví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
/POPD
ofor /f
sin sentido, simplemente funciones de lote antiguas. - El directorio y el archivo ni siquiera tienen que existir.fuente
%~f1
es la abreviatura de, por%~dpfn1
lo tanto, siéntase libre de usar%~f1
en su lugar. 🙂 - en el formato largo~
significa eliminar las comillas,d
significa unidad,p
significa ruta,n
solo sería nombre de archivo sin extensión, perofn
significa nombre de archivo con extensión. el1
significa 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
i
in%%~fi
es la variable definida en/F %%i
. p.ej. si cambiaste eso,/F %%a
entonces 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
cd
comando 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.drive
FOR /F %%i IN ("..\relativePath") DO echo absolute path: %%~fi
fallará si..\relativePath
contiene espaciosfor /?
sugiere usar letras mayúsculas para nombres de variables, para evitar confusión con los parámetros de sustitución/F
no 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 latokens
palabra clave:FOR /F "tokens=*" %%I IN ("..\relative Path\*") DO echo absolute path: %%~fI
Esto 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
%0
y%1
asimismo:%~dpnx0
para una unidad totalmente calificada + ruta + nombre + extensión del lote por sí mismo,%~f0
también es suficiente;%~dpnx1
para una unidad completa + ruta + nombre + extensión de su primer argumento [si es un nombre de archivo],%~f1
también es suficiente;%~f1
funcionará 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
,%~nx0
y%~x0
puede 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%~p1
y%~n1
trabajará para encontrar la ruta o el nombre del primer argumento,%~nx1
y%~x1
no agregará + mostrará la extensión, a menos que ya lo haya usado en la línea de comandos.fuente
%~dpnx1
es 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 .%~dpnx1
da la ruta totalmente calificada del primer argumento. No es relativo en absoluto, y tampoco es relativo al directorio actual. Eld
es para la unidad,p
es para la ruta,n
es para el nombre de archivo sin sufijo,x
es para el sufijo,1
es 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:\project
salida 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.txt
En 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:\Projects
fuente
fuente