web-dev-qa-db-fra.com

Échappement des parenthèses entre parenthèses pour le fichier de commandes

Voici ce que j'essaie de faire:

(
@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

Donc, avoir copié cela dans le presse-papiers. J'ai essayé ce qui suit:

(
@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

Mais cela semble également affecter mes parenthèses RECHERCHÉES car je reçois une erreur. Pour tester cela, j'ai simplement fait:

(
@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

Hey! Cela fonctionne presque, le texte est copié jusqu'au "s" dans "ceci". Il ne copie pas les dernières parenthèses, ni évidemment les F. Des idées?

35
user1759622

Il est évident que vous avez besoin de trois carets :-)

(
@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

Pourquoi? C'est un peu délicat ...

Tout d'abord, l'analyseur analyse le bloc et échappe la partie this^^^) À this^), La parenthèse a été échappée ici la première fois.

Mais comme vous avez utilisé un canal, le bloc complet sera traduit et transféré vers une nouvelle instance cmd.exe.
C:\Windows\system32\cmd.exe /S /D /c" ( @ echo This is some code is ... & @ echo for something (like this^) )"

Et dans la nouvelle instance, il est nécessaire à nouveau d'échapper à la parenthèse fermante.
C'est tout!

Et pour plus d'informations, vous pouvez lire une question similaire
SO: pourquoi l'expansion retardée échoue-t-elle à l'intérieur d'un bloc de code canalisé

45
jeb

Si vous êtes confus par le nombre de carets, rappelez-vous qu'il est toujours ne puissance de 2 moins 1. Alternativement, rappelez-vous que la première fois que vous ajoutez 2, la deuxième fois 4, la troisième fois 8, ...

Par exemple, (testé sur XP)

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

L'instruction echo est lue en premier normalement lorsque DOS analyse le fichier de commandes (1), en second lieu parce qu'il s'agit d'une commande interne canalisée (DOS semble vouloir des programmes dans des canaux, et les commandes internes ne sont pas des programmes) (3), troisième parce qu'elle est dans une liste de mots commandée par 'for/f' (voir pour /?) (7), et une quatrième fois pour les raisons déjà données dans ce fil (15).

Je peux également noter que personnellement, je considère que le codage est bâclé de laisser un échappement correct des caractères chauds juste parce que DOS ignore le d'échappement manquant dans ce cas particulier. Donc, si je voulais faire écho à une paire de parenthèses littérales dans l'exemple ci-dessus, je donnerais chacun 15 carets, même si la parenthèse ouvrante n'en a pas besoin. Alors, quiconque lit mon code n'a pas à se demander pourquoi une parenthèse est citée et l'autre non. Et comment modifier la citation sous modification de code.

5

Ma solution lorsque j'ai besoin d'utiliser une parenthèse fermante dans mes échos encapsulés est de créer une variable nommée% endPar% au début de mon script, quelque chose comme ceci:

@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

Je l'ai changé un peu et l'ai testé deux fois.

Le code renvoie simplement les échos dans un fichier appelé tmp, vous dirigez ensuite le contenu du fichier vers le clip, et il est prêt à être collé où vous le souhaitez.

1
Sirach Matthews

Le triple caret ne fonctionne pas dans toutes les situations. prenez ce qui suit:

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

le contenu de file.txt est:

TEST THIS: (SOME WORDING! ^)
1
psm1034