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.

Foi útil?

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 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:

http://www.robvanderwoude.com/batchfiles.php

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top