Как перебрать файлы, соответствующие шаблону в пакетном файле - PullRequest
174 голосов
/ 02 сентября 2008

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

  • Показать базовое имя 'f'
  • Выполнить действие над 'f.in'
  • Выполнить еще одно действие для 'f.out'

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

Ответы [ 7 ]

269 голосов
/ 02 сентября 2008

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

80 голосов
/ 02 сентября 2008

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

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

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

5 голосов
/ 02 сентября 2008

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

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

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

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

РЕДАКТИРОВАТЬ: Это фантастика! Я как-то пропустил страницу в документах, которая показала, что вы можете делать многострочные блоки в цикле FOR. Я собираюсь пойти придется вернуться и переписать некоторые командные файлы сейчас ...

3 голосов
/ 02 сентября 2008

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

@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
3 голосов
/ 02 сентября 2008

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

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

0 голосов
/ 15 октября 2017

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

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

0 голосов
/ 23 февраля 2016

Код ниже фильтрует имена файлов, начиная с заданной подстроки. Его можно изменить в соответствии с различными потребностями, работая с извлечением подстроки подстроки и оператором 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...