Como executar um loop pelos arquivos correspondentes ao curinga no arquivo de lote

Eu tenho um conjunto de nomes de arquivos base, para cada nome ‘f’ existem exatamente dois arquivos, ‘f.in’ e ‘f.out’. Eu quero escrever um arquivo de lote (no Windows XP), que passa por todos os nomes de arquivos, para cada um deve:

  • Exibe o nome base ‘f’
  • Realize uma ação em ‘f.in’
  • Realize outra ação em ‘f.out’

Eu não tenho como listar o conjunto de nomes de arquivos base, além de procurar por * .in (ou * .out) por exemplo.

Supondo que você tenha dois programas que processam os dois arquivos, process_in.exe e process_out.exe:

for %%f in (*.in) do ( echo %%~nf process_in "%%~nf.in" process_out "%%~nf.out" ) 

%% ~ nf é um modificador de substituição, que expande% f apenas para um nome de arquivo. Veja outros modificadores em https://technet.microsoft.com/en-us/library/bb490909.aspx (no meio da página) ou apenas na próxima resposta.

Você pode usar essa linha para imprimir o conteúdo da sua área de trabalho:

 FOR %%I in (C:\windows\desktop\*.*) DO echo %%I 

Uma vez que você tenha a variável %%I , é fácil executar um comando nela (basta replace a palavra echo pelo programa)

Além disso, a substituição de referências de variável FOR foi aprimorada Agora você pode usar a seguinte syntax opcional:

 %~I - expands %I removing any surrounding quotes (") %~fI - expands %I to a fully qualified path name %~dI - expands %I to a drive letter only %~pI - expands %I to a path only (directory with \) %~nI - expands %I to a file name only %~xI - expands %I to a file extension only %~sI - expanded path contains short names only %~aI - expands %I to file attributes of file %~tI - expands %I to date/time of file %~zI - expands %I to size of file %~$PATH:I - searches the directories listed in the PATH environment variable and expands %I to the fully qualified name of the first one found. If the environment variable name is not defined or the file is not found by the search, then this modifier expands to the empty string [https://ss64.com/nt/syntax-args.html][1] 

Nos exemplos acima, %I e PATH podem ser substituídos por outros valores válidos. A syntax %~ é terminada por um nome de variável FOR válido. Escolher nomes de variables ​​maiúsculas como %I torna-o mais legível e evita confusão com os modificadores, que não diferenciam maiúsculas de minúsculas.

Você pode obter a documentação completa digitando FOR /?

A maneira mais fácil, como eu vejo, é usar um loop for que chama um segundo arquivo de lote para processamento, passando o segundo arquivo para o nome base.

De acordo com o for /? help, basename pode ser extraído usando a opção nifty ~ n. Então, o script base seria:

 for %%f in (*.in) do call process.cmd %%~nf 

Em seguida, em process.cmd, suponha que% 0 contenha o nome base e aja de acordo. Por exemplo:

 echo The file is %0 copy %0.in %0.out ren %0.out monkeys_are_cool.txt 

Pode haver uma maneira melhor de fazer isso em um script, mas sempre fui um pouco confuso sobre como extrair vários comandos em um único loop em um arquivo em lote.

EDIT: Isso é fantástico! De alguma forma, perdi a página nos documentos que mostravam que você poderia fazer blocos de várias linhas em um loop FOR. Eu vou ter que voltar e rewrite alguns arquivos em lote agora …

Existe uma ferramenta normalmente usada em MS Servers (tanto quanto me lembro) chamado forfiles :

O link acima contém ajuda, bem como um link para a página de download da Microsoft.

Expandindo no post do Nathans . O seguinte irá fazer o lote de trabalho em um arquivo de lote.

 @echo off if %1.==Sub. goto %2 for %%f in (*.in) do call %0 Sub action %%~nf goto end :action echo The file is %3 copy %3.in %3.out ren %3.out monkeys_are_cool.txt :end 

O código abaixo filtra nomes de arquivos que começam com uma determinada substring. Ele poderia ser alterado para atender a diferentes necessidades trabalhando na extração de substring subfname e na instrução IF:

 echo off rem filter all files not starting with the prefix 'dat' setlocal enabledelayedexpansion FOR /R your-folder-fullpath %%F IN (*.*) DO ( set fname=%%~nF set subfname=!fname:~0,3! IF NOT "!subfname!" == "dat" echo "%%F" ) pause 

Ecoando f.in e f.out irá separar o conceito de loop e não loop quando usado em um loop for / f.

 ::Get the files seperated echo f.in>files_to_pass_through.txt echo f.out>>files_to_pass_through.txt for /F %%a in (files_to_pass_through.txt) do ( for /R %%b in (*.*) do ( if "%%a" NEQ "%%b" ( echo %%b>>dont_pass_through_these.txt ) ) ) ::I'm assuming the base name is the whole string "f". ::If I'm right then all the files begin with "f". ::So all you have to do is display "f". right? ::But that would be too easy. ::Let's do this the right way. for /f %%C in (dont_pass_through_these.txt) ::displays the filename and not the extention echo %~nC ) 

Embora você não tenha perguntado, uma boa maneira de passar comandos para f.in e f.out seria …

 for /F %%D "tokens=*" in (dont_pass_through_these.txt) do ( for /F %%E in (%%D) do ( start /wait %%E ) ) 

Um link para todos os comandos do Windows XP: link

Peço desculpas se não respondi corretamente. A questão foi muito difícil para eu ler.