12

私は素晴らしいコンソール ファイル マネージャー (Senh Liu による eXtreme) を持っています。それは短いパス/ファイル名を変数として menu.bat に渡します。

完全なフォルダ名 + 長いファイル名を生成するにはどうすればよいですか?

例:

  • 入力変数 = "P:\MYPROG~1\SHELLS\ZBACKUP\REFSTO~1.BAL"
  • ターゲット変数 = "P:\MyPrograms\SHELLS\zBackup\RefsToMyData.bal"

私は次のことを試しました:

  • SET my_file=%~2:

    echo %my_file%生成:"P:\MYPROG~1\SHELLS\ZBACKUP\REFSTO~1.BAL"

  • FOR /F "tokens=* USEBACKQ" %%F IN (`dir /B %2`) DO SET my_file=%%~fF:

    echo %my_file%生成:"P:\MYPROG~1\SHELLS\zBackup\RefsToMyData.bal"

  • FOR /F "tokens=* USEBACKQ" %%F IN (`dir /B %2`) DO SET my_file=%%~dpnxF:

    echo %my_file%生成:"P:\MYPROG~1\SHELLS\zBackup\RefsToMyData.bal"

4

10 に答える 10

7

簡単な解決策: PowerShell を使用します。

PS C:\> (Get-Item 'P:\MYPROG~1\SHELLS\ZBACKUP\REFSTO~1.BAL').FullName
P:\MyPrograms\SHELLS\zBackup\RefsToMyData.bal

次のように、バッチ ファイルに PowerShell 呼び出しを組み込むことができます。

@echo off

setlocal

for /f "usebackq delims=" %%f in (
  `powershell.exe -Command "(Get-Item '%~1').FullName"`
) do @set "var=%%~f"

echo %var%

出力:

C:\> test.cmd P:\MYPROG~1\SHELLS\ZBACKUP\REFSTO~1.BAL
P:\MyPrograms\SHELLS\zBackup\RefsToMyData.bal

PowerShell は、サポートされているすべての Windows バージョンで利用できます。

  • Windows XP SP3 および Server 2003 SP2: PowerShell v2が利用可能
  • Windows Vista および Server 2008: PowerShell v1 が同梱されています (既定ではインストールされません)。PowerShell v2 は利用可能です
  • Windows 7 および Server 2008 R2: PowerShell v2 がプリインストールされ、PowerShell v3が利用可能(バッテリーは含まれていません)
  • Windows 8 および Server 2012: PowerShell v3 がプリインストールされています

何らかの理由 (管理上の制限など) で PowerShell を使用できない場合は、代わりに VBScript を使用します。

name = WScript.Arguments(0)

Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(name) Then
  Set f = fso.GetFile(name)
ElseIf fso.FolderExists(name) Then
  Set f = fso.GetFolder(name)
  If f.IsRootFolder Then
    WScript.Echo f.Path
    WScript.Quit 0
  End If
Else
  'path doesn't exist
  WScript.Quit 1
End If

Set app = CreateObject("Shell.Application")
WScript.Echo app.NameSpace(f.ParentFolder.Path).ParseName(f.Name).Path

上記のような VBScript は、次のようなバッチ ファイルで使用できます。

@echo off & setlocal

for /f "delims=" %%f in ('cscript //NoLogo script.vbs "%~1"') do @set "var=%%~f"

echo %var%

ただし、これには追加のスクリプト ファイルが必要です。

于 2013-09-06T12:52:11.643 に答える
3

これは完全な長いパス名を返しますが、次の条件に依存します:
A) ツリー内のファイルが多すぎない (時間がかかるため)
B) ツリー内にターゲット (長い) ファイル名が 1 つしかない。

@echo off
for /f "delims=" %%a in (' dir /b "%~1" ') do set "file=%%a"
for /f "delims=~" %%a in ("%~dp1") do cd /d "%%a*"
for /f "delims=" %%a in ('dir /b /s /a-d "%file%" ') do set "var=%%a"
echo "%var%"

それを呼び出すと、mybat "d:\MYPROG~1\SHELLS\zBackup\REFSTO~1.BAL"
これが返されました:

"d:\MyPrograms\SHELLS\zBackup\RefsToMyData.bal"

于 2013-09-07T05:27:38.517 に答える
2

そして、予想外に簡単な解決策が 1 つあります。

 echo lcd %some_path%|ftp

例を示すために編集: 100% ではない

d:\>echo lcd C:\Files\Download\MYMUSI~1\iTunes\ALBUMA~1 |ftp  
Local directory now C:\Files\Download\MYMUSI~1\iTunes\Album Artwork. 
于 2013-10-11T23:23:53.140 に答える
1
@echo off
setlocal
rem this need to be a short name to avoid collisions with dir command bellow
cd C:\BALBAL~1\BLBALB~1\
set "curr_dir=%cd%"
set "full_path="

:repeat

for /f "delims=" %%f in ('for %%d in ^(.^) do @dir  /a:d /n /b "..\*%%~snd"') do ( 
    set "full_path=%%f\%full_path%"
)

cd ..

if ":\" NEQ "%cd:~-2%" (
    goto :repeat
) else (
    set "full_path=%cd%%full_path%"
)

echo --%full_path%--
cd %curr_dir%
endlocal

パスは最初にハードコードされていますが、変更またはパラメーター化できます。ファイルの完全な名前を簡単に取得できるため、ここではディレクトリのソリューションにすぎません。

編集

ファイルとディレクトリに対して機能するようになり、パラメーターを渡すことができます。

   @echo off

rem ---------------------------------------------
rem ---------------------- TESTS ----------------
rem ----------------------------------------------

md "c:\test\blablablablabl\bla bla bla\no no no no no no\yes yes yes" >nul 2>&1
md "c:\test\1                      b1\1\" >nul 2>&1
for %%t in ("c:\test\blablablablabl\bla bla bla\no no no no no no\yes yes yes") do set t_dir=%%~st
for %%t in ("c:\test\1                      b1\1\") do set t_dir2=%%~st
echo a>"%t_dir2%a"
echo a>"%t_dir2%a a.txt"

echo testing "%t_dir%\\"
call :get_full_name "%t_dir%\\"
echo(
echo testing "%t_dir2%a"
call :get_full_name "%t_dir2%a"
echo(
echo testing "%t_dir2%a a.txt" with return variable
call :get_full_name  "%t_dir2%a a.txt" test_var
echo  return variable : -- %test_var% --
goto :eof

rem -------------------------------------

:get_full_name [%1 - short path to a file or directory ; %2 - if set stores the result in variable with that name] 
setlocal
if not exist "%~1" ( echo file/dir does not exist & exit /b 2 )

set "curr_dir=%cd%"
for /f "delims=" %%n  in ('dir /b /n "%~dps1\%~snx1"') do set "name=%%n"

cd "%~dps1"
set "full_path="
:repeat
for /f "delims=" %%f in ('for %%d in ^(.^) do @dir  /a:d /n /b "..\*%%~snd"') do ( 
    set "full_path=%%~f\%full_path%"
)
cd ..
if ":\" NEQ "%cd:~-2%" (
    goto :repeat
) else (
    set "full_path=%cd%%full_path%"
)

echo %full_path%%name%
cd %curr_dir%
endlocal & if "%~2" NEQ ""  set "%~2=%full_path%%name%"

そしてテスト出力:

testing "c:\test\BLABLA~1\BLABLA~1\NONONO~1\YESYES~1\\"
c:\test\blablablablabl\bla bla bla\no no no no no no\yes yes yes\

testing "c:\test\1B1~1\1\a"
c:\test\1                      b1\1\a

testing "c:\test\1B1~1\1\a a.txt" with return variable
c:\test\1                      b1\1\a a.txt
 return variable : -- c:\test\1                      b1\1\a a.txt --
于 2013-09-06T12:32:25.687 に答える
1

and を使用した 1 回の試行はWMIC、 andWin32_Directoryを使用するよりもおそらく遅くなりますcddir、現在のディレクトリは変更されません。

@echo off
:get_full_name [%1 - short path to a file or directory ; %2 - if set stores the result in variable with that name]
setlocal 
if not exist "%~1" ( echo file/dir does not exist & exit /b 2 )
for /f "delims=" %%n  in ('dir /b /n "%~dps1\*%~snx1"') do set "name=%%n"

set "short_path=%~dps1"
set "short_path=%short_path:~0,-1%"
set "drive=%short_path:~0,2%"

set "full_name="

:repeat
set "short_path=%short_path:\=\\%"
set "short_path=%short_path:'=\'%"

FOR /F "usebackq skip=2 delims=" %%P in (`WMIC path win32_directory where name^='%short_path%'  get Path^,FileName /Format:Textvaluelist.xsl`) do  for /f "delims=" %%C in ("%%P") do (
    set "_%%C"
)
set "_Path=%_Path:~0,-1%"

set full_name=%_FileName%\%full_name%
if "%_Path%" NEQ "" (
    set "short_path=%drive%%_Path%"
    goto :repeat
) else (
    set full_name=%drive%\%_FileName%\%full_name%
)
echo %full_name%%name%
endlocal  if "%~2" NEQ ""  set "%~2=%full_path%%name%"

まだ十分にテストされていません....

于 2013-09-08T08:40:27.773 に答える