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

StackOverflow https://stackoverflow.com/questions/39615

Вопрос

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

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

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

Это было полезно?

Решение

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

Кроме того, была улучшена замена ссылок на переменные 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 /?

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

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

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

Ссылка выше содержит справку, а также ссылку на страницу загрузки 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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top