Как перебирать файлы, соответствующие подстановочному знаку в пакетном файле


У меня есть набор базовых имен файлов, для каждого имени ' f ' есть ровно два файла, 'f.in-и " f. out". Я хочу написать пакетный файл (в Windows XP), который проходит через все имена файлов, для каждого из них он должен:

  • отображение базового имени 'f'
  • выполнить действие на 'f.in'
  • выполните еще одно действие на 'f. out'

У меня нет никакого способа перечислить набор базовых имен файлов, кроме поиска *.in (или *.вне) для образец.

7 159

7 ответов:

предполагая, что у вас есть две программы, которые обрабатывают два файла, process_in.exe и process_out.exe:

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

%%~nf-это модификатор подстановки, который расширяет %f только до имени файла. См. другие модификаторы вhttps://technet.microsoft.com/en-us/library/bb490909.aspx (на полпути вниз по странице) или просто в следующем ответе.

вы можете использовать эту строку для печати содержимого вашего рабочего стола:

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

после %%I переменная на нем легко выполнить команду (просто замените слово echo своей программой)

кроме того, была улучшена замена ссылок на переменные Теперь вы можете использовать следующий необязательный синтаксис:

%~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]

в приведенных выше примерах %I и путь может быть заменен другим действительным ценности. Элемент %~ синтаксис завершается a допустимо для имени переменной. Выбор имен переменных в верхнем регистре, таких как %I делает его более читабельным и позволяет избежать путаницы с модификаторами,которые не чувствительны к регистру.

вы можете получить полную документацию, введя FOR /?

в соответствии с for/? справка, basename можно извлечь с помощью опции nifty ~n. Итак, базовый скрипт будет читать:

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

потом, в процессе.cmd, предположим, что %0 содержит базовое имя и действовать соответственно. Например:

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

возможно, есть лучший способ сделать это в одном скрипте, но я всегда было немного туманно о том, как вытащить несколько команд в одном цикле for в пакетном файле.

EDIT: это фантастика! Я как-то пропустил страницу в документах, которая показала, что вы можете делать многострочные блоки в цикле FOR. Я собираюсь пойти, чтобы вернуться и переписать некоторые пакетные файлы сейчас...

есть инструмент, обычно используемый на серверах MS (насколько я помню) под названием forfiles:

ссылка выше содержит справку, а также ссылку на страницу загрузки microsoft.

расширения Натанса пост. Ниже будет выполнена партия заданий в одном пакетном файле.

@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

приведенный ниже код фильтрует имена файлов, начиная с заданной подстроки. Он может быть изменен в соответствии с различными потребностями, работая над извлечением подстроки subfname и оператором 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

Эхо f.in и f. out будет отделять концепцию того, что петля и что не петля при использовании в цикле 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
)

хотя вы не спрашивали, хороший способ передать команды в f.in и f. out будет...

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

ссылка на все команды Windows XP:ссылке

Я прошу прощения, если я не ответил на это правильно. Этот вопрос мне было очень трудно прочитать.