2011-06-16 3 views
57

Quelqu'un peut-il expliquer comment cela fonctionne?Explique comment fonctionne le hachage de variable newline dos-batch

@echo off 
REM Creating a Newline variable (the two blank lines are required!) 
set NLM=^ 


set NL=^^^%NLM%%NLM%^%NLM%%NLM% 
REM Example Usage: 
echo There should be a newline%NL%inserted here. 

émet:

There should be a newline 
inserted here. 

de How can you echo a newline in batch files?

+0

Y at-il une raison de faire autre que de créer une nouvelle ligne vide? – Mechaflash

+0

Il y en a beaucoup, j'ai ajouté quelques explications à ma réponse – jeb

Répondre

82

L'astuce utilise le comportement du caret.
également expliqué à Long commands split over multiple lines in Vista/DOS batch (.bat) file

Le caret est un caractère d'échappement pour le caractère suivant, ou à la fin de ligne est utilisé comme caractère multiligne, mais cela est à peu près le même. À la fin de la ligne, il échappe simplement le caractère suivant, dans ce cas le <Linefeed>, mais il y a une fonctionnalité cachée, donc si le caractère échappé est <LF> il est ignoré et le caractère suivant est lu et échappé, mais ceci Charater sera toujours échappé, même s'il s'agit également d'un <LF>.

Maintenant vous pouvez comprendre

set NLM=^ 


rem Two empty lines are required here 

Le NLM-variable contient exactement un caractère <LF>. Mais si vous essayez de l'utiliser avec echo Line1%NLM%Line2, il échoue, car l'analyseur cesse d'analyser un seul <LF>.
Mais cela fonctionne

echo Line1^ 

Line2 

Vous avez donc besoin d'ajouter un saut de ligne se sont échappés dans la ligne et est le NL-variable. La variable NL ne comporte que trois caractères.
NL=^<LF><LF> Et si cela est développé, il crée un seul <LF> échappé comme premier <LF> après que le signe d'insertion sera ignoré.

Btw. À mon avis, il est beaucoup plus facile d'utiliser des sauts de ligne avec une expansion retardée, car il n'y a pas besoin d'échapper à quoi que ce soit.
Dans cet exemple, j'utilise %=EMPTY=% au lieu d'une ligne vide (pour auto-commenter), mais comme la variable =EMPTY= ne peut pas exister, elle sera étendue à une ligne vide.

setlocal EnableDelayedExpansion 
(set NLM=^ 
%=EMPTY=% 
) 
echo Line1!NLM!Line2 

EDIT: Ajoute quelques conseils pour utiles en utilisant le <LF>

1) Utilisation comme nouvelle ligne dans une echo

setlocal EnableDelayedExpansion 
(set LF=^ 
%=EMPTY=% 
) 
echo Line1!LF!Line2 

2) Il permet de regrouper les commandes dans un bloc de parenthèse

setlocal EnableDelayedExpansion 
(set LF=^ 
%=EMPTY=% 
) 
(
    echo Line1%LF%set x=4%LF%echo !x!%LF% 
) 

3) Créer un EOL-chararcter (presque) vide dans une boucle FOR/F, comme <LF> est le délimiteur de ligne un EOL de <LF> est le même que celui vide.

FOR /F ^"eol^=^ 

delims^=^" %%a in (myFile.php) do echo %%a 

4) Utiliser LF pour le texte de séparation dans une boucle FOR/F

setlocal EnableDelayedExpansion 
(set LF=^ 
%=EMPTY=% 
) 
set "var=Content1;Content2" 
FOR /F "delims=" %%a in ("%var:;=!LF!%") do (
    echo %%a 
) 
+0

Grand sujet! Comment est-ce que j'insère un caractère de nouvelle ligne dans une chaîne que j'échouerai après avoir construit la chaîne multi-ligne? Merci – RGuggisberg

+0

@RGuggisberg Je ne suis pas sûr que j'ai eu votre question, mais peut-être que vous voulez dire 'set multiStr = Line1! LF! Line2 & echo! MultiStr!' – jeb

+0

Ahhh oui! Je l'ai. Merci jeb – RGuggisberg

5

Il semble un way qui fonctionne aussi avec le tube:

(echo 1st line^ 
&echo 2nd line) | sort 
+0

Mais cela trie aussi chaque ligne. Donc, cette astuce ne fonctionne pas pour la concaténation de fichiers multi-lignes – Armin

Questions connexes