3

バッチ ファイル内に、ファイル パスを含む変数があります。

SET VAR1=C:\Folder1\Folder2\File.txt

ディレクトリ構造を抽出して取得したい:

C:\Folder1\Folder2\

パラメータとして渡されると思われる場所を使用する必要があるこのようなスレッドを読みました。試してみましたが、うまくいきません。ファイルパスを含む変数を使用して、探している出力を取得するにはどうすればよいですか?%~dp00%~dpVAR1

また、問題を複雑にするために、条件内でこれらすべてを実行IFする必要があります。つまり、変数が宣言されたら、!代わりに%(setlocal enableextensions enabledelayedexpansionこれを可能にするためにスクリプトの冒頭で宣言しました) で参照する必要があります。 )。

どんな助けでも大歓迎です!

ありがとう!

アンドリュー

4

4 に答える 4

8

環境変数でパラメータ展開構文を使用しようとしています - これは機能しません。しかし、やりたいことは比較的簡単にできます。

CALL を使用する (比較的遅い):

(...
  call :getPath "!var!" var
  ...
)
exit /b

:getPath
set "%2=%~dp1"
exit /b

変数にワイルドカードが含まれていないと仮定して、FOR を使用する (高速)

(...
  for %%F in ("!var!") do set "var=%%~dpF"
 ...
)

変数にワイルドカードが含まれている可能性がある場合は、FOR を使用します (これも高速です)。

(...
  for /f "delims=" %%F in ("!var!") do set "var=%%~dpF"
 ...
)

注 1: 変数に絶対パスが含まれていない場合、すべてのソリューションは名前を絶対パスに解決しようとし、完全な絶対パスを返します。たとえば、var に が含まれfoobar\test.txtている場合、ファイルが見つからなくても、ソリューションには現在のディレクトリへのフル パスが含まれます。のようなものc:\pathToCurrentDirectory\foobar\

注 2: 上記のすべてのソリューションでは、パスからすべての引用符が削除されます。

注 3: パスには!文字が含まれている可能性があり、展開時に問題が発生する%~dp1%%~dpF、遅延展開が有効になっているために問題が発生します。遅延拡張は、 と値に が含まれている場合の両方^を破損します。と の両方を保護するソリューションがあります。上記の最後のソリューションに適用されたデモを次に示します。保護には通常の展開が必要であり、コード ブロック内にいるため、少なくとも 1 つの CALL が必要です。サブルーチンがなくてもできますが、サブルーチンを使用すると簡単です。サブルーチンは、変数の名前が であると想定します。!!!^var

(...
  call :getPath
 ...
)
exit /b

:getPath
set "var=!var:"=!"
set "var=!var:^=^^^^!"
set "var=%var:!=^^^!%" !
for /f "delims=" %%F in ("!var!") do set "var=%%~dpF" !
exit /b
于 2013-02-13T12:22:09.833 に答える
1

(もう一度) 多くの質問が同じトピック (文字列の制約、または文字列の分割) に関するものだと思います。

コード全体を提供する代わりに、テンプレートを提供して、%~dpVAR!機能しなかった理由を説明します。

まず、なぜ%~dpVAR!うまくいかなかったのか。

モディファイアに入る前に、パラメーターについて説明しましょう。バッチ ファイルがパラメーターを相互に解析できることはご存知かもしれません。これらのパラメーターは、0 ~ 9 の数字の前に 1 つのパーセント記号 (%) を使用して呼び出すことができます。私が知る限り (誰かがもっと解析する方法を作ったかもしれません)、解析できるパラメーターは 9 つだけです。それは間違っていると思うかもしれません (10 個のパラメーターがありますよね?)。パラメーター 1 ~ 9 はバッチ ファイル (または関数内の関数) に解析されます。%0 はバッチ ファイル (または関数名) のファイル パスです。見てみると、 %~dp0%0 と (実際にはそうではない) 類似点があります。これについては以下で説明します。

第二に、用語%~dp0には修飾子が含まれています。修飾子は、変数 (パラメーターとforループで宣言されたパラメーターの場合のみ、%%i のような二重のパーセント記号を持つものを知っています) とパラメーターを変更するものです。修飾子dは、パラメーターをドライブ文字のみにp展開し、パラメーターをパスのみに展開します。これらは矛盾していると思うかもしれませんが、パラメーターを組み合わせて非常に奇抜なフォーマットを作成することができます。

ご覧のとおり、0 を変数名に置き換えようとして失敗しました。これは、そのようなものに指定されていないためです。

では、テンプレへ。

次のように、変数を制約する (そしてそれらを他の変数に入れる) ことができます。 set variable=!variable:~offset,amount!

混乱しているように見えても心配しないでください。これからコンポーネントについて説明します。

/aまず、スイッチがないことに注意してください。これは、これが数学関数ではないためです (なぜこれを追加したのかよくわかりません)。そのため、説明する前にnumbers、値が0123456789.

set numbers=!numbers:~5,1!

そのコード行を使用すると、numbersと等しくなり5ます。これは、元の値の小さいバージョンで変数を再作成しているためです (これは説明が難しいです)。ご覧のとおり、上記のテンプレートにある5場所があります。offsetこれは、最初の 5 文字をスキップし、変数を次のamount, または1文字として設定しているためです (これが得られることを本当に願っています)。

したがって、基本的には、オフセットとそれに含まれる文字の量によって決定される別の (または同じ) 変数の短い値として変数を設定します。

私はおそらくこれについての言葉を理解していないので、これが役立つことを本当に願っています.

誰かがこのかわいそうな人を、これをよりよく説明するリンクにリダイレクトできますか (試してみました!)?

于 2013-02-13T08:32:56.290 に答える