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?

Ondra Žižka
fonte

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
Wayne
fonte
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).

jeb
fonte
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 .

T.J. multidão
fonte
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 ^
Todd Partridge
fonte
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.

Mohammed Safwat
fonte
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