Dividir comandos longos em várias linhas através do arquivo em lotes do Windows


735

Como posso dividir comandos longos em várias linhas em um arquivo em lotes?

Respostas:


919

Você pode dividir linhas longas com o cursor ^, desde que lembre-se de que o cursor e a nova linha a seguir sejam completamente removidos. Portanto, se houver um espaço em que você esteja quebrando a linha, inclua um espaço. ( Mais sobre isso abaixo. )

Exemplo:

copy file1.txt file2.txt

seria escrito como:

copy file1.txt^
 file2.txt

95
Você pode iniciar a próxima linha sem espaço se adicionar um espaço imediatamente antes ^e depois do texto do comando.
Joseph Daigle

4
@SebaIllingworth - Não, você sempre pode adicionar [ESPAÇO] + [^] e duas linhas em branco para criar um total de 2 feeds de linha quando for echoeditado.
James K

12
Por segurança sempre terminam com linha em branco ao usar carets, consulte quilates simples no arquivo de lote consome toda a memória
Matt Wilkie

4
@ GavinMiller: "caret ^ após copiar e file1.txt em uma nova linha não funcionará" Isso não é verdade. Você pode dividir a linha em qualquer lugar, inclusive no meio de uma palavra, como co^␍py ^␍file1 ^␍file2. Eu sugiro que você excluir seu comentário a confusão evitar, especialmente porque esta questyion é um tão popular
Borodin

3
Uma dica aqui é que o ^ deve ser o último caractere na linha - ou seja, não há espaços depois. Eu estava tendo problemas com isso e acabei tendo vários espaços após o sinal de intercalação - não é facilmente visível no editor que estava usando.
precisa saber é o seguinte

267

A regra para o sinal de intercalação é:

Um sinal de intercalação no final da linha anexa a próxima linha; o primeiro caractere da linha anexada será escapado.

Você pode usar o sinal de intercalação várias vezes, mas a linha completa não deve exceder o comprimento máximo da linha de ~ 8192 caracteres (Windows XP, Windows Vista e Windows 7).

echo Test1
echo one ^
two ^
three ^
four^
*
--- Output ---
Test1
one two three four*

echo Test2
echo one & echo two
--- Output ---
Test2
one
two

echo Test3
echo one & ^
echo two
--- Output ---
Test3
one
two

echo Test4
echo one ^
& echo two
--- Output ---
Test4
one & echo two

Para suprimir a fuga do próximo caractere, você pode usar um redirecionamento.

O redirecionamento deve ser logo antes do sinal de intercalação. Mas existe uma curiosidade com o redirecionamento antes do sinal de intercalação.

Se você colocar um token no cursor, ele será removido.

echo Test5
echo one <nul ^
& echo two
--- Output ---
Test5
one
two


echo Test6
echo one <nul ThisTokenIsLost^
& echo two
--- Output ---
Test6
one
two

E também é possível incorporar feeds de linha na string:

setlocal EnableDelayedExpansion
set text=This creates ^

a line feed
echo Test7: %text%
echo Test8: !text!
--- Output ---
Test7: This creates
Test8: This creates
a line feed

A linha vazia é importante para o sucesso. Isso funciona apenas com expansão atrasada; caso contrário, o restante da linha é ignorado após o avanço da linha.

Funciona porque o cursor no final da linha ignora o próximo avanço de linha e escapa do próximo caractere, mesmo que o próximo caractere também seja um avanço de linha (os retornos de carro são sempre ignorados nesta fase).


O bloco de código final com o exemplo de avanço de linha não exibe a linha em branco, mesmo que esteja lá. (Pelo menos, ele não aparece no IE7) Tente reformatar usando uma citação em bloco.
dbenham

5
A questão é: devemos oferecer suporte a uma ferramenta ruim que não segue as regras (alguém chama de navegador, mas não é) ou você deve mudar para um navegador?
jeb

1
eu tinha aspas duplas ao redor dos meus valores, como no conjunto var = "text here ^", mas não funciona. Remova as aspas duplas e está tudo bem.
Rjt 5/04

1
@jeb, escreveu-se um exemplo não script de cmd, mas depois encontrei esta pergunta: stackoverflow.com/questions/4643376/...
RJT

Isso não funciona se a próxima linha começar com aspas: copy ^[newline]"file1.txt" ^[newline]"file2.txt"não funciona! Eu tive que adicionar um espaço: copy ^[newline] "file1.txt" ^[newline] "file2.txt".
Alexander Gelbukh

70

(Isso é basicamente uma reescrita da resposta de Wayne, mas com a confusão em torno do cursor resolvida. Então, eu a publiquei como CW. Não tenho vergonha de editar respostas, mas reescrevê-las completamente parece inadequado.)

Você pode dividir as linhas longas com o sinal de intercalação ( ^), lembre-se de que o sinal de intercalação e a nova linha a seguir são removidos inteiramente do comando; portanto, se você o colocar onde seria necessário um espaço (como entre parâmetros), verifique se para incluir também o espaço (antes da^ ou no início da próxima linha - essa última opção pode ajudar a deixar mais claro que é uma continuação).

Exemplos: (todos testados no Windows XP e Windows 7)

xcopy file1.txt file2.txt

pode ser escrito como:

xcopy^
 file1.txt^
 file2.txt

ou

xcopy ^
file1.txt ^
file2.txt

ou mesmo

xc^
opy ^
file1.txt ^
file2.txt

(Esse último funciona porque não há espaços entre the xce the ^, e não há espaços no início da próxima linha. Portanto, quando você remove a ^e a nova linha, obtém ...xcopy ).

Para legibilidade e sanidade, provavelmente é melhor quebrar apenas entre parâmetros (não se esqueça de incluir o espaço).

Certifique-se de que não^ seja a última coisa em um arquivo em lotes, pois parece haver um grande problema com isso .


18

Vários comandos podem ser colocados entre parênteses e espalhados por várias linhas; então algo assim echo hi && echo hellopode ser colocado assim:

( echo hi
  echo hello )

Também variáveis ​​podem ajudar:

set AFILEPATH="C:\SOME\LONG\PATH\TO\A\FILE"
if exist %AFILEPATH% (
  start "" /b %AFILEPATH% -option C:\PATH\TO\SETTING...
) else (
...

Também notei com os sinais de intercalação ( ^) que os ifcondicionais gostavam que eles seguissem apenas se um espaço estivesse presente:

if exist ^

1
A linha cmd1.bat && cmd2.baté diferente da forma parens: execute cmd2.batse for cmd1.batexecutado com êxito (sem configuração %errorcode%). O último formulário é executado incondicionalmente. Um tanto inesperado (pelo menos para mim) é que, obviamente, você não pode usar a combinação de ambos + ou seja, adicionar &&antes da quebra de linha.
Paul Michalik

( echo <line break here> hello )resulta em uma linha vazia.
Karl Morrison

melhor e mais limpa resposta! sinais de intercalação são feios e problemáticos em regex
neoscribe

9

Parece, no entanto, que a divisão no meio dos valores de um loop for não precisa de um sinal de intercalação (e, na verdade, tentar usar um será considerado um erro de sintaxe). Por exemplo,

for %n in (hello
bye) do echo %n

Observe que nenhum espaço é necessário após o olá ou antes do tchau.


Obviamente, isso faz parte da forsintaxe: os separadores de elementos no "conjunto" são espaço, vírgula, ponto e vírgula, sinal de igual, caractere TAB e novas linhas.
Aacini

Mas e se a doparte contiver várias if-elseinstruções / aninhadas ?
Vicky Dev

Em seguida, você pode simplesmente usar parênteses para incluir as instruções como para% n in (olá tchau) do (eco% n echo% n) #
Mohammed Safwat
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.