15

現在実行中のバッチ ファイルのフォルダー名を取得する必要があります。次の構文を使用して現在のディレクトリをループしようとしています (これは現在間違っています)。

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

「mydir」変数値を検索文字列として渡すことができないといういくつかの問題があります。コマンドを渡した場合にのみ機能するようです。構文が間違っていて、その理由がわかりません。

私の考えでは、フォルダー文字列を「\」区切り文字でループすることでしたが、これも問題を引き起こしています。各ループで変数を設定すると、最後に設定された値が現在のフォルダー名になります。たとえば、次のパスがあるとします。

C:\Folder1\Folder2\Folder3\Archive.bat

値「Folder3」を解析することを期待しています。

その名前は、バッチ ファイルのさらに下に作成する別のフォルダーの一部になるため、その値を解析する必要があります。

誰かが助けてくれたらどうもありがとう。私は完全に間違ったツリーを吠えているかもしれないので、他のアプローチも大いに受け入れられるでしょう.

4

13 に答える 13

21

これらの提案のいくつかに苦労した後、次の1つのライナーがうまく使用されていることがわかりました(Windows 2008で)

for %%a in (!FullPath!) do set LastFolder=%%~nxa
于 2011-01-03T19:08:23.110 に答える
10

あなたはそれにかなり近かった:)これはうまくいくはずです:

@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

何らかの理由で、for コマンドは区切り文字として '\' を好まないため、すべての '\' を ';' に変換しました。最初 ( SET mydir=%mydir:\=;%)

于 2008-11-11T14:47:54.797 に答える
6

現在のディレクトリの最後のセグメントを探していたときに、この古いスレッドを見つけました。以前の作家の答えは、私を次のように導きます。

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

前に説明したように、%_LAST_SEGMENT_% で作成されたすべてのパスを引用符で囲むことを忘れないでください (私の例で %CD% で行ったように)。

これが誰かに役立つことを願っています...

于 2012-09-24T13:25:40.017 に答える
4

この質問は少し古いですが、私は何度も解決策を探してきたので、これが私がまとめたばかりのまったく新しい考え方です。

秘訣は、目的のパスをたどり、1レベルバックアップして、置換用のフォルダーマスクを作成してから、フォルダーマスクを何も置き換えないことです。

テストするには、任意のディレクトリのコマンドスクリプト(.cmd)にコピーして貼り付け、実行します。それはあなたが現在いる最も深いディレクトリだけを吐き出します。

ノート:

  • %〜dp0を任意のパスに置き換えます(そのままでは、バッチファイルの実行元の最も深いフォルダーが返されます。これは%cd%と同じではありません)。
  • 'pathtofind'変数を指定するときは、引用符がないことを確認してください。たとえば、 "c:\ somepath"ではなくc:\somepathです。
  • フォルダマスキングの元のアイデアは私のものです
  • パス内のスペースは問題ありません
  • フォルダの深さは問題ではありません
  • これは、このバッチスクリプトのヒントhttp://www.dostips.com/DtCodeBatchFiles.php#Batch.FindAndReplaceの天才によって可能になりました。

これが他の誰かに役立つことを願っています。

@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
于 2010-07-04T21:40:19.890 に答える
2

元のポスターの問題に戻るには:

たとえば、次のパスがあるとします。C:\ Folder1 \ Folder2 \ Folder3\Archive.bat値「Folder3」を解析することを期待します。

そのための簡単な解決策は次のとおりです。

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

'Folder3'を与えます。ファイル/パスは存在する必要はありません。もちろん、....親の親ディレクトリの場合、または......その上のディレクトリの場合(など)も機能します。

于 2012-05-10T14:36:30.733 に答える
2

3行のスクリプトで結果が得られます...

目標を達成するための2つの追加の方法が見つかりました。この質問に対する他の回答とは異なり、バッチ「関数」や遅延拡張は必要なく、Tim Peelの回答がディレクトリの深さで持っている制限もありません:

@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

REVISION: 私の新しいリビジョンの後、ここに出力例があります:

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

これは、スクリプトがフォルダー名の「#」または「,」を処理しないことを意味しますが、処理するように調整できます。

補遺: dostipsフォーラムで誰かに尋ねたところ、さらに簡単な方法が見つかりました。

@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
于 2011-11-03T04:08:55.970 に答える
1

いずれかのフォルダーの名前にスペースが含まれている場合のわずかな変更 - 操作の前後にスペースを「:」に置き換えます。

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
于 2008-11-11T15:56:56.530 に答える
1

なんてこった。これは非常に簡単で、CD を使用せずにメモリ内で行う方が高速です。

これは、パスの最後の 2 つのディレクトリを取得します。任意の行の最後のトークンを取得するには、必要に応じて変更してください。これに基づいた私の元のコードは、私自身の目的のためにもっと複雑です。

参考までに、私は enabledelayedexpansion を使用しているため、おそらく感嘆符付きのパスは許可されませんが、これは修正される可能性があります。

また、プレーン ドライブ ルートでは機能しません。これは、いくつかの方法で回避できます。入力パスの末尾やカウンターを確認するか、トークンを変更して動作を確認するなど。

@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
于 2010-10-18T20:04:23.077 に答える
0

これが最終的に得られたものです(もう少し粗雑で、非常に深くしか説明できません:)

@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%
于 2008-11-11T15:04:23.797 に答える
0

私が使用している Windows のバージョン (win2k3) であるかどうかはわかりませんが、FOR ループでは、単一の文字列を反復処理するのに役立つものは何もありません。私の観察 (および FOR /? 情報) によると、FOR への入力の行ごとに 1 つの反復が得られ、これを行内で反復するように変更する方法はありません。特定の行に対して複数のトークンに分割できますが、それは FOR ループ本体の 1 回の呼び出しにすぎません。

これらの回答の CALL :LABEL アプローチは素晴らしい仕事をしていると思います。これを見るまで知らなかったのは、「;」および "," は両方とも引数の区切りとして認識されます。したがって、バックスラッシュをセミコロンに置き換えたら、ラベルを呼び出して、SHIFT を使用して繰り返すことができます。

ここに他の人が投稿したものに取り組んで、私は以下の解決策を持っています。最後のフォルダー名を取得する代わりに、実際には既知のディレクトリ名まですべてを検索したかった..これが以下に実装されているものです。

@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
于 2010-06-11T19:10:46.440 に答える
0

FOR コマンドのバッチ ファイルでは、%whatever の先頭に追加の % を追加する必要があります (例: %%whatever)。

'echo %~p0' は、バッチ ファイルの現在のディレクトリを出力します。

于 2008-11-11T14:22:10.590 に答える
-2

残念ながら、これはある程度の深さに置くとうまく機能しますが、山の頂上にいることに問題があります...このプログラムを「C:\ Windows」に入れると、たとえば「C:\Windows」になります。 、「Windows」は予期されていません。それでも素晴らしい仕事であり、それでも損傷は修復することができます。私のアプローチ:

@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

そして、それは今私にとってはうまく機能しています、アイデアのおかげで、私はしばらくの間そのようなものを探していました。

于 2010-08-23T00:54:28.420 に答える