^
エスケープシーケンスを回避する方法があります。
遅延展開で変数を使用できます。以下は、小さなバッチスクリプトのデモです
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
echo !line!
または、FOR / Fループを使用することもできます。コマンドラインから:
for /f "delims=" %A in ("<html>") do @echo %~A
または、バッチスクリプトから:
@echo off
for /f "delims=" %%A in ("<html>") do echo %%~A
特別なオペレーターが好き後に遅延展開と変数の展開の両方が発生しているため、これらのメソッドの仕事がある理由は<
、>
、&
、|
、&&
、||
解析されます。Windowsコマンドインタープリター(CMD.EXE)がスクリプトを解析する方法を参照してください。詳細については。
sin3.14は、パイプが複数のエスケープを必要とする可能性があることを指摘しています。例えば:
echo ^^^<html^^^>|findstr .
パイプが複数のエスケープを必要とする理由は、パイプの両側が新しいCMDプロセスで実行されるため、行が複数回解析されるためです。コードのパイプブロック内で遅延拡張が失敗する理由を参照してください。ウィンドウのパイプ実装の多くの厄介な結果の説明。
パイプを使用するときに複数のエスケープを回避する別の方法があります。独自のCMDプロセスを明示的にインスタンス化し、引用符で単一のエスケープを保護できます。
cmd /c "echo ^<html^>"|findstr .
エスケープを回避するために遅延拡張手法を使用したい場合は、さらに多くの驚きがあります(CMD.EXEの設計の専門家であれば驚くことではないかもしれませんが、このことを説明する公式のMicroSoftのドキュメントはありません)。
パイプの各サイドは独自のCMD.EXEプロセスで実行されますが、プロセスは遅延拡張状態を継承しないことに注意してください。デフォルトではオフになっています。したがって、独自のCMD.EXEプロセスを明示的にインスタンス化し、/ V:ONオプションを使用して遅延拡張を有効にする必要があります。
@echo off
setlocal disableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo !test!|findstr .
親バッチスクリプトでは遅延拡張がオフになっていることに注意してください。
しかし、親スクリプトで遅延拡張が有効になっている場合、すべての地獄が壊れます。以下は機能しません。
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
REM - the following command fails
cmd /v:on /c echo !test!|findstr .
問題は!test!
、親スクリプトで展開されているため、新しいCMDプロセスが保護されていない<
とを解析しようとしていること>
です。
をエスケープすることもできますが!
、!
が引用されているかどうかに依存するため、注意が必要です。
引用されていない場合は、二重のエスケープが必要です。
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c echo ^^!test^^!|findstr .
引用されている場合、単一のエスケープが使用されます。
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
cmd /v:on /c "echo ^!test^!"|findstr .
しかし、すべてのエスケープを回避する驚くべきトリックがあります-パイプの左側を囲むことで、親スクリプトが!test!
時期尚早に拡張されるのを防ぎます。
@echo off
setlocal enableDelayedExpansion
set "line=<html>"
(cmd /v:on /c echo !test!)|findstr .
ただし、かっこを使用すると、バッチパーサーが最後に余分な(おそらく不要な)スペースを導入するため、それは無料の昼食ではないと思います。
Aint Batch Scripting Fun ;-)