获得短文件名完整路径和长文件名 [英] Get full path and long file name from short file name

查看:415
本文介绍了获得短文件名完整路径和长文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很好的控制台文件管理器(由Senh刘极限),它通过短路径/文件名作为变量到menu.bat。

I have an nice console file manager (eXtreme by Senh Liu), it passes short path/filenames as variables to a menu.bat.

我如何可以生成一个完整的文件夹名称+长文件名?

How can I generate a full folder name + long file name?

例如:


  • 输入变量=P:\\ MYPROG〜1 \\壳\\ ZBACKUP \\ REFSTO〜1.BAL

  • 目标变量=P:\\ MyPrograms \\壳\\ zBackup \\ RefsToMyData.bal

我曾尝试以下内容:


  • SET my_file =%〜2

回声%my_file%生产:P:\\ MYPROG〜1 \\壳\\ ZBACKUP \\ REFSTO〜1.BAL

FOR / F令牌= *有usebackq%% f由于(`DIR / B%2`)DO SET my_file = %%〜fF的

回声%my_file%生产:P:\\ MYPROG〜1 \\壳\\ zBackup \\ RefsToMyData.bal

FOR / F令牌= *有usebackq%% f由于(`DIR / B%2`)DO SET my_file = %%〜dpnxF

回声%my_file%生产:P:\\ MYPROG〜1 \\壳\\ zBackup \\ RefsToMyData.bal

推荐答案

下面应该与任何有效的路径工作,只要它的的UNC路径。路径可以是绝对或相对的。它可能会使用短文件名或长名(或混合物)。的路径可指代一个文件夹或文件。

The following should work with any valid path, as long as it is not a UNC path. The path may be absolute or relative. It may use short file names or long names (or a mixture). The path may refer to a folder or a file.

结果将与结束\\ ,如果它是一个文件夹,没有 \\ 在结束时,如果它是一个文件

The result will end with \ if it is a folder, no \ at end if it is a file.

:getLongPath 常规期望一个inputPath变量名作为第1个参数,以及一个可选的返回变量名作为第二个参数。该inputPath变量应该包含一个有效的路径。如果返回变量不speciied,然后将结果显示在屏幕上(用引号)。如果指定返回变量,那么结果在变量返回(不带引号)。

The :getLongPath routine expects an inputPath variable name as the 1st argument, and an optional return variable name as the 2nd argument. The inputPath variable should contain a valid path. If the return variable is not speciied, then the result is ECHOed to the screen (enclosed in quotes). If the return variable is specified, then the result is returned in the variable (without quotes).

时,如果你正在返回一个变量延迟扩展禁用该例程只应被调用。如果所谓延迟扩展启用,那么结果会被它是否包含字符损坏。

The routine should only be called when delayed expansion is disabled if you are returning a variable. If called with delayed expansion enabled, then the result will be corrupted if it contains the ! character.

测试用例(仅适用于我的机器)是在脚本的顶部,底部的实际程序。

Test cases (for my machine only) are at the top of the script, the actual routine at the bottom.

@echo off
setlocal
for %%F in (

  "D:\test\AB2761~1\AZCFE4~1.TXT"
  "AB2761~1\AZCFE4~1.TXT"
  "D:\test\AB2761~1\ZZCE57~1\"
  "D:\test\a b\a z.txt"
  "D:\test\a b\z z"
  "."
  "\"
  "x%%&BAN~1\test"
  "x%% & bang!\test"

) do (
  echo(
  echo resolving %%F
  set "shortPath=%%~F"
  call :getLongPath shortPath longPath
  set longPath
)

echo(
echo(
set "shortPath=D:\test\AB2761~1\AZCFE4~1.TXT"
set shortPath
echo Calling :getLongPath with with no return variable
call :getLongPath shortPath

exit /b

:getLongPath  path  [rtnVar]
setlocal disableDelayedExpansion
setlocal enableDelayedExpansion
for %%F in ("!%~1!") do (
  endlocal
  set "sourcePath=%%~sF"
  set "sourceFile=%%~nxF"
)
if not exist "%sourcePath%" (
  >&2 echo ERROR: Invalid path
  exit /b 1
)
set "rtn="
2>nul cd "%sourcePath%" || (
  cd "%sourcePath%\.."
  for /f "eol=: delims=" %%F in ('dir /b /a-d "%sourceFile%"') do set "rtn=%%F"
)
:resolveFolders
for %%F in ("%cd%") do (
  cd ..
  set "folder=%%~nxF"
)
if defined folder for /f "eol=: delims=" %%: in ('dir /b /ad') do (
  if /i "%%~snx:" equ "%folder%" (
    set "rtn=%%:\%rtn%"
    goto :resolveFolders
  )
)
set "rtn=%cd%%rtn%
( endlocal
  if "%~2" equ "" (echo "%rtn%") else set "%~2=%rtn%"
)

=== OUTPUT ===

=== OUTPUT ===

resolving "D:\test\AB2761~1\AZCFE4~1.TXT"
longPath=D:\test\a b\a z.txt

resolving "AB2761~1\AZCFE4~1.TXT"
longPath=D:\test\a b\a z.txt

resolving "D:\test\AB2761~1\ZZCE57~1\"
longPath=D:\test\a b\z z\

resolving "D:\test\a b\a z.txt"
longPath=D:\test\a b\a z.txt

resolving "D:\test\a b\z z"
longPath=D:\test\a b\z z\

resolving "."
longPath=D:\test\

resolving "\"
longPath=D:\

resolving "x%&BAN~1\test"
longPath=D:\test\x% & bang!\test\

resolving "x% & bang!\test"
longPath=D:\test\x% & bang!\test\


shortPath=D:\test\AB2761~1\AZCFE4~1.TXT
Calling :getLongPath with with no return variable
"D:\test\a b\a z.txt"

如果你想运行上面的code,那么我建议你完全删除之间的所有测试场景code @回响:getLongPath 。然后,你可以简单地调用脚本,传递任何有效的路径作为第一个参数。正确的长路径应打印结果。

If you want to run the above code, then I suggest you completely delete all the test scenario code between @echo off and :getLongPath. Then you can simply call the script, passing any valid path as the first argument. The correct long path should be printed as a result.

我很惊讶多么困难,这是使用批处理来解决。我不认为这是JScript或VBS更容易的(事实上,安斯加尔找到了一个不错的解决方案VBS)的。但我喜欢安斯加尔的简单的PowerShell的解决方案 - 容易得多

I was amazed how difficult this was to solve using batch. I don't think it is much easier with JScript or VBS (Actually, Ansgar found a nice VBS solution). But I like Ansgar's simple PowerShell solution - so much easier.

更新

我发现在那里,如果从内部FOR循环称为高于code未能一个不起眼的情况下,和路径恰好有FOR变量在其中。它也不会正确报告与野生卡作为一个错误的路径,它不具有延迟扩展工作时启用路径中包含

I found an obscure case where the above code fails if called from within a FOR loop, and the path happens to have the FOR variable within it. It also doesn't properly report a path with wild cards as an error, and it doesn't work with delayed expansion enabled when the path contains !.

所以我在下面创建一个修改后的版本。我是pretty相信它应该真正在工作的所有的情况下,除了UNC路径,可能不与路径UNI code。我打包它作为一个简单的调用程序,完成与内置的文档。它可以保留为一个独立的脚本,或并入一个较大的脚本。

So I created a modified version below. I'm pretty confident it should truly work in all situations, except for UNC paths and possibly not with unicode in the path. I packaged it up as an easy to call procedure, complete with built in documentation. It can be left as a stand-alone script, or incorporated into a larger script.

@echo off
:getLongPath
:::
:::getLongPath  PathVar  [RtnVar]
:::getLongPath  /?
:::
:::  Resolves the path contained in PathVar into the full long path.
:::  If the path represents a folder then it will end with \
:::
:::  The result is returned in variable RtnVar.
:::  The result is echoed to the screen if RtnVar is not specified.
:::
:::  Prints this documentation if the first argument is /?

if "%~1" equ "" (
  >&2 echo ERROR: Insufficient arguments. Use getLongPath /? to get help.
  exit /b 1
)
if "%~1" equ "/?" (
  for /f "delims=" %%A in ('findstr "^:::" "%~f0"') do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo(!ln:~3!
    endlocal
  )
  exit /b 0
)
setlocal
set "notDelayed=!"
setlocal disableDelayedExpansion
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%F in ("!%~1!") do (
  endlocal
  set "sourcePath=%%~sF"
  set "sourcePath2=%%F"
  set "sourceFile=%%~nxF"
)
if not exist "%sourcePath%" (
  >&2 echo ERROR: Invalid path
  exit /b 1
)
set "sourcePath3=%sourcePath2:**=%"
set "sourcePath3=%sourcePath3:?=%"
if "%sourcePath3%" neq "%sourcePath2%" (
  >&2 echo ERROR: Invalid path
  exit /b 1
)
set "rtn="
2>nul cd "%sourcePath%" || (
  cd "%sourcePath%\.."
  for /f "eol=: delims=" %%F in ('dir /b /a-d "%sourceFile%"') do set "rtn=%%F"
)
:resolveFolders
for %%F in ("%cd%") do (
  cd ..
  set "folder=%%~nxF"
)
if defined folder for /f "delims=: tokens=1,2" %%A in ("%folder%:%rtn%") do for /f "eol=: delims=" %%F in ('dir /b /ad') do (
  if /i "%%~snxF" equ "%%A" (
    set "rtn=%%F\%%B"
    goto :resolveFolders
  )
)
set "rtn=%cd%%rtn%"
if not defined notDelayed set "rtn=%rtn:^=^^%"
if not defined notDelayed set "rtn=%rtn:!=^!%"
if not defined notDelayed (set "!=!==!") else set "!="
for %%A in ("%rtn%") do (
  endlocal
  endlocal
  if "%~2" equ "" (echo %%~A%!%) else set "%~2=%%~A"!
)

我也适应安斯加尔的VBS到混合的JScript /批处理脚本。它应该提供相同的结果作为上述纯批处理脚本,但JScript是更简单效仿。

I also adapted Ansgar's VBS into a hybrid JScript/batch script. It should provide the identical result as the pure batch script above, but the JScript is much simpler to follow.

@if (@X)==(@Y) @end /* harmless hybrid line that begins a JScrpt comment
@echo off

:getLongpath
:::
:::getLongPath  PathVar  [RtnVar]
:::getLongPath  /?
:::
:::  Resolves the path contained in PathVar into the full long path.
:::  If the path represents a folder then it will end with \
:::
:::  The result is returned in variable RtnVar.
:::  The result is echoed to the screen if RtnVar is not specified.
:::
:::  Prints this documentation if the first argument is /?

::************ Batch portion ***********
if "%~1" equ "" (
  >&2 echo ERROR: Insufficient arguments. Use getLongPath /? to get help.
  exit /b 1
)
if "%~1" equ "/?" (
  for /f "delims=" %%A in ('findstr "^:::" "%~f0"') do (
    set "ln=%%A"
    setlocal enableDelayedExpansion
    echo(!ln:~3!
    endlocal
  )
  exit /b 0
)
setlocal
set "notDelayed=!"
setlocal disableDelayedExpansion
set "rtn="
for /f "delims=" %%A in ('cscript //E:JScript //nologo "%~f0" %*') do set "rtn=%%A"
if not defined rtn exit /b 1
if not defined notDelayed set "rtn=%rtn:^=^^%"
if not defined notDelayed set "rtn=%rtn:!=^!%"
if not defined notDelayed (set "!=!==!") else set "!="
for %%A in ("%rtn%") do (
  endlocal
  endlocal
  if "%~2" equ "" (echo %%~A%!%) else set "%~2=%%~A"!
)
exit /b 0

************ JScript portion ***********/
var env=WScript.CreateObject("WScript.Shell").Environment("Process");
var fso=WScript.CreateObject("Scripting.FileSystemObject");
var app=WScript.CreateObject("Shell.Application");
var inPath=env(WScript.Arguments.Item(0));
var folder="";
var f;
if (fso.FileExists(inPath)) {
  f=fso.GetFile(inPath);
}
else if (fso.FolderExists(inPath)) {
  folder="\\"
  f=fso.GetFolder(inPath);
  if (f.IsRootFolder) {
    WScript.StdOut.WriteLine(f.Path);
    WScript.Quit(0);
  }
}
else {
  WScript.StdErr.WriteLine('ERROR: Invalid path');
  WScript.Quit(1);
}
WScript.StdOut.WriteLine( app.NameSpace(f.ParentFolder.Path).ParseName(f.Name).Path + folder);

这篇关于获得短文件名完整路径和长文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆