web-dev-qa-db-ja.com

バッチファイルの括弧内の括弧のエスケープ

これは私がやろうとしていることです:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something (like this)
)|clip

それをクリップボードにコピーします。私は以下を試しました:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something ^(like this^)
)|clip

しかし、これはエラーを受け取るため、WANTED括弧にも影響を与えるようです。これをテストするために、私は単にやった:

(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something ^(like this^)
FFF
)|clip

おい!これはほぼ機能し、テキストは「this」内の「s」までコピーされます。最後の括弧、または明らかにFはコピーしません。何か案は?

35
user1759622

そこに3つのキャレットが必要であることは明らかです:-)

_(
@echo This is some code that is
@echo Important to echo exactly as-is
@echo Even if I use parenthesis
@echo for something (like this^^^)
)|clip
_

どうして?それは少しトリッキーです...

最初に、パーサーはブロックを解析し、_this^^^)_から_this^)_までの部分をエスケープします。括弧はここで初めてエスケープされました。

ただし、パイプを使用すると、完全なブロックが変換され、新しいcmd.exeインスタンスに転送されます。
C:\Windows\system32\cmd.exe /S /D /c" ( @ echo This is some code is ... & @ echo for something (like this^) )"

また、新しいインスタンスでは、閉じ括弧をエスケープする必要があります。
それで全部です!

詳細については、同様の質問を読むことができます
SO:パイプされたコードブロック内で遅延展開が失敗する理由

45
jeb

キャレットカウントで混乱した場合は、常に2の累乗-1であることを忘れないでください。または、最初に2を追加したとき、2番目に4を追加し、3番目に8を追加することを覚えておいてください。

例(XPでテスト済み)

(
for /f "tokens=* delims=" %%S in (
'echo X^^^^^^^^^^^^^^^& ^^^^^^^^^^^^^^^| ^^^| find " "'
) do @echo %%S
) | find "X"

Echoステートメントは、DOSがバッチファイルを解析するときに最初に正常に読み取られます(1)、2番目はパイプされた内部コマンドであるため(DOSはパイプ内のプログラムを必要とし、内部コマンドはプログラムではないようです)(3)、3番目は'for/f'コマンド駆動のWordリスト(/?を参照)(7)。このスレッドで既に与えられている理由により、4回目(15)。

個人的には、DOSがその特定のケースで欠落しているエスケープをたまたま無視するからといって、ホットキャラクターを適切にエスケープしないようにするのはずさんなコーディングだと思います。したがって、上の例で括弧のリテラルペアをエコーし​​たい場合は、開始括弧で必要ない場合でも、15個のキャレットをそれぞれ指定します。そうすれば、私のコードを読む人は、なぜ括弧の1つが引用され、もう1つが引用されないのか不思議に思う必要はありません。そして、コード修正の下で引用を修正する方法。

5

カプセル化されたエコーで閉じかっこを使用する必要がある場合の私の解決策は、次のようなスクリプトの先頭に%endPar%という名前の変数を作成することです。

@set "endPar=)"
@echo This is some code that is>tmp
@echo Important to echo exactly as-is>>tmp
@echo Even if I use parenthesis>>tmp
@echo for something (like this%endPar%>>tmp
@type tmp|clip
@del tmp

少し変えて2回テストしました。

コードは単にtmpと呼ばれるファイルにエコーを出力し、ファイルのコンテンツをクリップしてクリップするだけで、どこにでも貼り付けることができます。

1
Sirach Matthews

トリプルキャレットはすべての状況で機能するわけではありません。次のようにします。

IF EXIST file.txt (
ECHO ...OK
) ELSE (
ECHO TEST THIS: (SOME WORDING! ^^^)   > file.txt
)

file.txtの内容は次のとおりです。

TEST THIS: (SOME WORDING! ^)
1
psm1034