14

私のスクリプトの 1 つで、IFステートメント内にかっこを含む変数を使用する必要がありますが、シナリオによっては、文字列に閉じかっこがないか、スクリプトが* was unexpected at this time(実際にはアスタリスクではない) 途中で終了します。

 

@echo off

SET path=%programFiles(x86)%
echo Perfect output: %path%
IF NOT "%path%" ==  "" (
    REM Variable is defined
    echo Broken output:  %path%
)

pause >nul

出力

Perfect output: C:\Program Files (x86)
Broken output:  C:\Program Files (x86

 

C:\Program Files (x86)これは、閉じ括弧がステートメントの終わりであるIFと見なされ、ステートメントが完了する前に終了するためだと思います/知っていますecho

これを回避する簡単な方法はありますか?できれば頼らずに

  1. 複数行のコードを実行する必要があるため、単一行のIFステートメント、
  2. GOTO実用的ではないため、大量のs
  3. SETLOCAL EnableDelayedExpansionその方法はOS間で一貫して機能しないことをどこかで読んだことを思い出したので、!path!の代わりに使用します。%path%

そうでない場合は、提供された最も信頼性の高いソリューションが何であれ、喜んで受け入れます。

 

(シナリオは議論の余地がありません。これは、問題の洗練された集中的な例にすぎません。構造は、実際のスクリプトのように、このようにする必要があります。理由については説明しません。問題を混乱させ、実際の問題から注意をそらすだけです。)

4

5 に答える 5

10

まず、PATH 変数を自分用に使用しないでください。これは予約済みの環境変数です。独自の目的で使用すると、スクリプトが壊れる可能性があります。

最も簡単な解決策は、遅延展開を使用することです。プラットフォームが CMD.EXE を使用している限り、遅延拡張にアクセスできます。

しかし、拡張を遅らせることなく機能させる比較的簡単な方法があります。消える引用符を使用できます。引用符は、コマンドが解析される間、FOR 変数の名前として解析時に存在します。実行時間の前に何も展開されません。

@echo off

SET mypath=%programFiles(x86)%
echo Perfect output: %mypath%
IF NOT "%mypath%" ==  "" (
  REM Variable is defined
  for %%^" in ("") do echo fixed output:  %%~"%mypath%%%~"
)

pause >nul

編集 - 遅延拡張を使用する場合: コメントへの応答

私は通常、遅延拡張が必要な​​場合 (より正確には、有利な場合) にのみ使用します。そうは言っても、通常、バッチコードの一部で有利だと思います。

主な利点

  • ブロック内の変数への変更を確認するためのコード ブロック内
  • 変数の名前を逆参照する場合。変数名がパラメーターとして渡される場合、変数の値は遅延展開によって取得できます。echo !%1!
  • 変数を引数として使用して検索および置換または部分文字列操作を行う場合: echo !var:%search%=%replace%!echo !var:%start%,%len%!.
  • 値を拡張する必要があり、エスケープや引用が必要な特殊文字について心配する必要がないときはいつでも:set "var=A&B" & echo !var!

上記を実行する方法は他にもありますが (最後の方法を除く)、遅延拡張は最も簡単で、最も効率的 (実行が最も高速) で、最も信頼性の高いオプションです。

主な欠点

  • 値に含まれる FOR 変数は!、遅延展開が有効になっている場合、展開時に破損します。この問題を回避するために、FOR ループ内で遅延展開のオンとオフを頻繁に切り替えます。
  • コマンド解析の多くの重要なフェーズが遅延展開の前に行われるため、「マクロ」(変数値内に含まれるコードの実行) の実行には適していません。非常に多くのバッチ機能は、遅延展開によって実行される「マクロ」では利用できません。
于 2012-08-14T03:09:36.760 に答える
1

ステートメント内の解決された変数から、ブロックが時期尚早に閉じられ)ています。 echoIF

)通常、 with をエスケープすることで修正できますが^)、環境変数を に解決するように変更することはできませんC:\Program Files (x86^)

この問題は、変数を引用符で囲むことで回避できます。

より簡単な例として:

> SET bad=a)b
> IF 1 == 1 ( ECHO %bad% )
b was unexpected at this time.
> IF 1 == 1 ( ECHO "%bad%" )
"a)b"
于 2012-08-14T00:32:01.857 に答える
-1

私がこれを間違って読んでいる場合は許してください。しかし、「NOT」が原因で、コントロールが括弧付きの if に入り、壊れた出力を実行していませんか?

どうですか:

@echo off

echo Perfect output: %programFiles(x86)%
IF NOT "%programFiles(x86^)%" ==  "" (
    REM Variable is defined
    echo Broken output:  %programFiles(x86)%
) 

pause >nul

?

于 2012-08-14T00:27:47.673 に答える