Windows XP arquivo de lote concat
-
19-09-2019 - |
Pergunta
Eu estou tentando realizar a seguinte tarefa ridícula:
Eu tenho um arquivo de texto contendo um conjunto de filesnames totalmente qualificados. Quero percorrer os arquivos e anexar cada linha para uma variável comum, que pode ser passado para uma ferramenta de linha de comando. Por exemplo, o arquivo pode ser:
C: \ dir \ test.txt
C: \ WINDOWS \ test2.txt
C: \ text3.txt
e eu gostaria de atribuí-los a alguma variável 'a' tal que:
a = "C:\dir\test.txt C:\WINDOWS\test2.txt C:\text2.txt"
A questão secundária é - o que é uma referência arquivo de lote bom? Eu estou encontrando algumas coisas no material Windows e um monte de sites de home-grown, mas nada particularmente completa.
Solução
Quanto a referências, SS64.com não é ruim. Rob van der Woude fica ligado com bastante frequência, também.
Como para o seu problema, isso é fácil:
@echo off
setlocal enableextensions enabledelayedexpansion
set LIST=
for /f %%x in (yourfile.txt) do (
set LIST=!LIST! "%%x"
)
echo %LIST%
endlocal
Mais em profundidade explicação:
setlocal enableextensions enabledelayedexpansion
Estamos permitindo expansão adiada aqui. Isto é crucial, pois de outra forma não seria capaz de manipular a lista de arquivos dentro do loop for
que se segue.
for /f %%x in (yourfile.txt) do (
set LIST=!LIST! "%%x"
)
itera for /f
mais linhas em um arquivo, por isso exatamente o que precisamos aqui. Em cada iteração do loop que acrescentar a seguinte linha para a variável LIST
. Observe o uso de !LIST!
vez do %LIST%
habitual. Isso sinaliza adiada expansão e garante que a variável fica reavaliados cada vez que este comando é executado.
Normalmente cmd
expande variáveis ??para os valores assim que uma linha é lido e analisado. Para cmd
uma única linha ou é uma linha ou tudo o que conta ??em> como uma linha, que passa a valer para blocos delimitados por parênteses, como o que usamos aqui. Assim, para cmd
o bloco completo é uma única instrução que é lido e analisado uma vez, independentemente de quantas vezes o interior do loop é executado.
Se nós teria usado %LIST%
aqui em vez de !LIST!
então a variável teria sido substituído imediatamente pelo seu valor (esvaziar naquele ponto) eo loop teria parecido com isto:
for /f %%x in (yourfile.txt) do (
set LIST= "%%x"
)
É claro que isso não é o que queríamos. expansão adiada garante que uma variável só é expandida quando o seu valor é realmente necessário. Neste caso, quando o interior do circuito de corridas e constrói uma lista de nomes de arquivo.
Depois, o %LIST%
variável ou !LIST!
(agora ele realmente não importa mais que usar) contém a lista de linhas do arquivo.
Curiosamente, a ajuda para o comando set
inclui exatamente este exemplo para a expansão atrasada:
Finalmente, o suporte para adiado expansão ambiente variável possui foi adicionado. Este apoio é sempre desativado por padrão, mas pode ser activado / desactivado por meio do comando / V interruptor de linha para CMD.EXE. Veja CMD /?
expansão de variáveis ??de ambiente atrasada é útil para se locomover pela limitações da atual expansão que acontece quando uma linha de texto é ler, não quando ele é executado. o seguinte exemplo demonstra a problema com variável imediato expansão:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "%VAR%" == "after" @echo If you see this, it worked )
nunca iria exibir a mensagem, uma vez a% VAR% em ambas as instruções IF é substituído quando o primeiro SE declaração é lida, uma vez que logicamente inclui o corpo da FI, que é uma instrução composta. Assim, o IF dentro da instrução composto é realmente comparar "antes" com "depois" que nunca serão iguais. Similarmente, o exemplo a seguir não funcionará como esperado:
set LIST= for %i in (*) do set LIST=%LIST% %i echo %LIST%
em que ele não vai construir uma lista de arquivos no diretório atual, mas em vez disso, apenas definir a lista variável para o último arquivo encontrado. Novamente, isso é porque o% LIST% é expandidas apenas uma vez quando o PARA declaração é lida, e naquele tempo a variável lista está vazia. Então o real loop para estamos executando é:
for %i in (*) do set LIST= %i
que apenas mantém a configuração de lista à último arquivo encontrado.
expansão de variáveis ??de ambiente atrasada permite a utilização de uma diferente caracteres (o ponto de exclamação) para expandir variáveis ??de ambiente no tempo de execução. Se a variável atraso expansão é activada, o que precede exemplos poderia ser escrito como se segue funcione como pretendido:
set VAR=before if "%VAR%" == "before" ( set VAR=after if "!VAR!" == "after" @echo If you see this, it worked ) set LIST= for %i in (*) do set LIST=!LIST! %i echo %LIST%
Outras dicas
O que você está depois pode ser feito com um PARA comando / F.
Aqui está um bom recurso que eu usei muitas vezes:
Um livro bom: Windows NT Shell Scripting por Tim Hill. A edição que eu tenho foi publicado em 1998, mas ainda é válida para programas de comando do Windows no Windows 2008.
type *commonfilepart* >> concat_result_file
OS: Windows Server 2003