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

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

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

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

Ответ 1

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

    for %%f in (*.in) do (

            echo %%~nf
            process_in "%%~nf.in"
            process_out "%%~nf.out"
    )

%% ~ nf - модификатор подстановки, который расширяет% f только до имени файла. Другие модификаторы в https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/batch.mspx?mfr=true (в середине страницы) или только в следующем ответе.

Ответ 2

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

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

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

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

Расширение на Натанс. Следующее выполнит задание в одном пакетном файле.

@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

Ответ 6

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

Ответ 7

Повторяя 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 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: ссылка

Извиняюсь, если я не ответил правильно. Мне очень трудно было прочитать этот вопрос.