Ignorar sinal de porcentagem no arquivo em lote

Eu tenho um arquivo em lotes que move arquivos de uma pasta para outra. O arquivo em lotes é gerado por outro processo.

Alguns dos arquivos que preciso mover têm a string “% 20” neles:

move /y "\\myserver\myfolder\file%20name.txt" "\\myserver\otherfolder" 

Isso falha ao tentar encontrar um arquivo com o nome:

 \\myserver\myfolder\file0name.txt 

Existe alguma maneira de ignorar % ? Eu não sou capaz de alterar o arquivo gerado para escaping disso, como dobrando sinais de porcentagem ( %% ), escapando com / ou ^ (circunflexo), etc.

Você deve ser capaz de usar um acento circunflexo (^) para escaping de um sinal de porcentagem .

Nota do editor: O link está morto agora; De qualquer forma: É % própria que escapa % , mas apenas em arquivos em lote, não no prompt de comando; ^ nunca escapa de % , mas no prompt de comando ele pode ser usado indiretamente para evitar a expansão de variables, somente em strings sem aspas .

O motivo pelo qual %2 está desaparecendo é que o arquivo em lote está substituindo o segundo argumento passado, e você parece não ter um segundo argumento. Uma maneira de contornar isso seria tentar foo.bat ^%1 ^%2... modo que, quando um %2 for encontrado em um comando, ele será realmente substituído por um literal %2 .

Você precisa usar %% neste caso. Normalmente, o uso de um ^ (circunflexo) funcionaria, mas para sinais de % você precisa duplicar.

No caso de %%1 ou %%i ou echo.%%~dp1 , porque % indica a input de um comando ou de uma variável (quando cercada por % ; %variable% )

Para conseguir o que você precisa:

 move /y "\\myserver\myfolder\file%%20name.txt" "\\myserver\otherfolder" 

Eu espero que isso ajude!

O título da pergunta é muito genérico , o que inevitavelmente atrai muitos leitores à procura de uma solução genérica.
Por outro lado, o problema do OP é exótico : a necessidade de lidar com um arquivo em lote gerado automaticamente e que não pode ser modificado : os sinais % não são escapados adequadamente.
A resposta aceita fornece uma solução inteligente para o problema específico – e exótico -, mas está fadada a criar confusão em relação à questão genérica .

Se nos concentrarmos na questão genérica :

Como você usa % como um caractere literal em um arquivo de lote / na linha de comando?

  • Dentro de um arquivo de lote , sempre escape % as %% , seja em strings sem aspas ou não; os seguintes rendimentos My %USERNAME% is jdoe , por exemplo:

     echo My %%USERNAME%% is %USERNAME% echo "My %%USERNAME%% is %USERNAME%" 
  • Na linha de comando (interativamente) – bem como ao usar as funções de invocação de shell das linguagens de script – o comportamento difere fundamentalmente dos arquivos batch internos : tecnicamente, % não pode ser escapado e não há uma única solução alternativa que funcione em todas as situações :

    • Em strings sem aspas , você pode usar o truque ” ^ name-disrupter” : para simplificar, coloque um ^ antes de cada % char , mas note que mesmo que você não esteja tecnicamente escapando % dessa forma (veja abaixo para mais); por exemplo, o seguinte novamente gera algo como My %USERNAME% is jdoe :

       echo My ^%USERNAME^% is %USERNAME% 
    • Em cadeias de caracteres com aspas duplas , você não pode escaping % , mas existem soluções alternativas :

      • Você pode usar strings sem aspas como acima, que então requer que você também ^ escape-todos os outros metacaracteres do shell, o que é complicado; esses metacaracteres são: & | < > " & | < > "

      • Alternativamente, se o programa de destino suportar ( deve funcionar com a maioria dos executáveis binários , mas não com arquivos de lote ), você pode representar % chars. como "%" ; por exemplo:

         echo "My "%"USERNAME"%" is %USERNAME%" 
    • A partir de linguagens de script , se você souber que está chamando um executável binário , poderá evitar todo o problema renunciando às funções de reconhecimento de shell em favor das variantes “sem shell” , como usar execFileSync vez de execSync em Node.js.


Informações básicas opcionais sobre o uso da linha de comando (interativa):

Dica do chapéu para jeb por sua ajuda com esta seção.

Na linha de comando (interativamente), % tecnicamente não pode ser escapado de forma alguma ; enquanto ^ é geralmente o caractere de escape do cmd.exe , ele não se aplica a % .

Como afirmado, não solução para cadeias de caracteres com aspas duplas , mas existem soluções alternativas para cadeias sem aspas :

A razão pela qual o truque ” ^ name-disrupter” funciona (algo como ^%USERNAME^% ) funciona :

  • “Interrompe” o nome da variável ; ou seja, no exemplo acima, cmd.exe procura uma variável chamada USERNAME^ , que (esperançosamente) não existe.

  • Na linha de comando – ao contrário dos arquivos em lote – as referências a variables indefinidas são mantidas como estão .

Tecnicamente, um único ^ dentro do nome da variável – em qualquer lugar dentro dele, contanto que não seja próximo a outro ^ – é suficiente, então %USERNAME^% , por exemplo, seria suficiente, mas eu sugiro adotar a convenção de colocar metodicamente ^ antes de cada % de simplicidade , porque também funciona para casos como up 20^% , onde a interrupção nem é necessária, mas é benigna, então você pode aplicá-la metodicamente , sem precisar pensar nas especificidades de a string de input.

A ^ antes de um % abertura , embora não seja necessário, é benigno, porque ^ escapa do caractere seguinte, se esse caractere precisa ser evitado – ou, neste caso, pode ser evitado – ou não. O efeito final é que tais ^ instâncias são, em última análise, removidas de strings não citadas .

Advertência em grande parte hipotética : ^ é na verdade um caractere legal em nomes de variables (veja o exemplo de jeb nos comentários); Se o nome da variável terminar com ^ , simplesmente coloque o “disruptivo” ^ em outro lugar no nome da variável, desde que não esteja diretamente ao lado de outro ^ (pois isso faria com que um ^ aparecesse na string resultante).
Dito isso, no (muito improvável) caso de sua variável ter um nome como ^b^ , você está sem sorte.

Nos arquivos em lote, o sinal de porcentagem pode ser “escapado” usando um sinal de porcentagem duplo (%%). Dessa forma, um único sinal de porcentagem será usado na linha de comando. de http://www.robvanderwoude.com/escapechars.php

Eu acho que tenho uma solução parcial funcionando. Se você estiver apenas procurando transferir arquivos com a string “% 20” em seu nome e não procurar uma solução mais ampla, você pode fazer com que um segundo arquivo em lote chame o primeiro com %% 2 como o segundo parâmetro. Dessa forma, quando seu programa tentar buscar o segundo parâmetro quando atingir o% 2 no nome do texto, ele replaceá o% 2 por um% 2 com escape, deixando o nome do arquivo inalterado.

Espero que isso funcione!