Reputation: 2281
I have a batch script that:
Example code:
set pathTmp=D:\a\b\c
set pathIn=%pathTmp%\in
set pathOut=%pathTmp%\out
for /f %%i in ('dir /b %pathIn%') do (
java XXX.jar %pathIn%\%%i >> %pathOut%\%%i
)
Now I'd like to modify it to read files from all subfolders of pathIn
and put the output file in the same subfolder but under pathOut
.
Example: if input file is in pathIn\zzz
, the output file must be in pathOut\zzz
.
How can I recreate the input subfolder structure inside output folder?
Upvotes: 0
Views: 183
Reputation: 34989
I would use xcopy
together with the /L
switch (to list files that would be copied) to retrieve the relative paths. For this to work, you need to change to the directory %pathIn%
first and specify a relative source path (for this purpose, the commands pushd
and popd
can be used).
For example, when the current working directory is D:\a\b\c\in
and its content is...:
D:\a\b\c\in | data.bin +---subdir1 | sample.txt | sample.xml \---subdir2 anything.txt
...the command line xcopy /L /I /S /E "." "D:\a\b\c\out"
would return:
.\data.bin .\subdir1\sample.txt .\subdir1\sample.xml .\subdir2\anything.txt 3 File(s)
As you can see there are paths relative to the current directory. To get rid of the summary line 3 File(s)
, the find ".\"
command line is used to return only those lines containing .\
.
So here is the modified script:
set "pathTmp=D:\a\b\c"
set "pathIn=%pathTmp%\in"
set "pathOut=%pathTmp%\out"
pushd "%pathIn%"
for /F "delims=" %%I in ('xcopy /L /I /S /E "." "%pathOut%" ^| find ".\"') do (
md "%pathOut%\%%I\.." > nul 2>&1
java "XXX.jar" "%%I" > "%pathOut%\%%I"
)
popd
Additionally, I placed md "%pathOut%\%%I\.." > nul 2>&1
before the java
command line so that the directory is created in advance, not sure if this is needed though. The redirection > nul 2>&1
avoids any output, including error messages, to be displayed.
I put quotation marks around all paths in order to avoid trouble with white-spaces or any special characters in them. I also quoted the assignment expressions in the set
command lines.
You need to specify the option string "delims="
in the for /F
command line, because the default options tokens=1
and delims=
TABSPACE would split your paths unintentionally at the first white-space.
Note that the redirection operator >>
means to append to a file if it already exists. To overwrite, use the >
operator (which I used).
Upvotes: 1
Reputation: 2248
You could do something like this:
@setlocal EnableDelayedExpansion
@echo off
set pathTmp=D:\a\b\c
set pathIn=%pathTmp%\in
set pathOut=%pathTmp%\out
REM set inLength=ADD FUNCTION TO CALCULATE LENGTH OF PATHIN
for /f %%i in ('dir /b /s %pathIn%') do (
set var=%%i
java XXX.jar %%i >> %pathOut%\!var:~%inLength%!
)
This will strip the length of the pathIn
directory from the absolute path leaving only the relative path. Then it appends the relative path onto the pathOut
var
You would need to find or write a function to get the length of the the pathIn string. Check out some solutions here.
Upvotes: 0