How to loop through files matching wildcard in bat

2019-01-03 04:46发布

I have a set of base filenames, for each name 'f' there are exactly two files, 'f.in' and 'f.out'. I want to write a batch file (in Windows XP) which goes through all the filenames, for each one it should:

  • Display the base name 'f'
  • Perform an action on 'f.in'
  • Perform another action on 'f.out'

I don't have any way to list the set of base filenames, other than to search for *.in (or *.out) for example.

7条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-03 04:55

Expanding on Nathans post. The following will do the job lot in one batch file.

@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楼-- · 2019-01-03 05:07

Assuming you have two programs that process the two files, process_in.exe and process_out.exe:

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

%%~nf is a substitution modifier, that expands %f to a file name only. See other modifiers in https://technet.microsoft.com/en-us/library/bb490909.aspx (midway down the page) or just in the next answer.

查看更多
forever°为你锁心
4楼-- · 2019-01-03 05:10

Echoing f.in and f.out will seperate the concept of what to loop and what not to loop when used in a for /f loop.

::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
)

Although you didn't ask, a good way to pass commands into f.in and f.out would be to...

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

A link to all the Windows XP commands:link

I apologize if I did not answer this correctly. The question was very hard for me to read.

查看更多
来,给爷笑一个
5楼-- · 2019-01-03 05:13

Easiest way, as I see it, is to use a for loop that calls a second batch file for processing, passing that second file the base name.

According to the for /? help, basename can be extracted using the nifty ~n option. So, the base script would read:

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

Then, in process.cmd, assume that %0 contains the base name and act accordingly. For example:

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

There might be a better way to do this in one script, but I've always been a bit hazy on how to pull of multiple commands in a single for loop in a batch file.

EDIT: That's fantastic! I had somehow missed the page in the docs that showed that you could do multi-line blocks in a FOR loop. I am going to go have to go back and rewrite some batch files now...

查看更多
【Aperson】
6楼-- · 2019-01-03 05:14

There is a tool usually used in MS Servers (as far as I can remember) called forfiles:

The link above contains help as well as a link to the microsoft download page.

查看更多
女痞
7楼-- · 2019-01-03 05:15

The code below filters filenames starting with given substring. It could be changed to fit different needs by working on subfname substring extraction and IF statement:

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
查看更多
登录 后发表回答