Como posso dividir comandos longos em várias linhas em um arquivo em lotes?
Como posso dividir comandos longos em várias linhas em um arquivo em lotes?
Respostas:
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
echo
editado.
co^␍py ^␍file1 ^␍file2
. Eu sugiro que você excluir seu comentário a confusão evitar, especialmente porque esta questyion é um tão popular
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).
copy ^[newline]"file1.txt" ^[newline]"file2.txt"
não funciona! Eu tive que adicionar um espaço: copy ^[newline] "file1.txt" ^[newline] "file2.txt"
.
(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 xc
e 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 .
Vários comandos podem ser colocados entre parênteses e espalhados por várias linhas; então algo assim echo hi && echo hello
pode 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 if
condicionais gostavam que eles seguissem apenas se um espaço estivesse presente:
if exist ^
cmd1.bat && cmd2.bat
é diferente da forma parens: execute cmd2.bat
se for cmd1.bat
executado 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.
( echo <line break here> hello )
resulta em uma linha vazia.
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.
for
sintaxe: os separadores de elementos no "conjunto" são espaço, vírgula, ponto e vírgula, sinal de igual, caractere TAB e novas linhas.
do
parte contiver várias if-else
instruções / aninhadas ?
^
e depois do texto do comando.