我有一个目录中的许多图像需要减去到另一个图像(另一个目录),但我不知道如何在批处理中自动执行此操作。有什么想法吗?
以下是批处理文件的目标:
- 创建输出目录
- 仅为处理过的文件创建 proc_path 目录
- 将目录中的图像减去另一个目录中的另一幅图像
我尽了最大努力创作了这个剧本的一部分。如果写得有点乱,我很抱歉,我知道我做的不对。希望你能理解。
@echo on
setlocal EnableDelayedExpansion
set "in_path=E:\Proc\Mer\"
set "out_path=E:\Proc\Abcde"
set "two_path=E:\Proc\Me\"
set "proc_path=E:\Proc\Proc_Mer_Fi"
::Don't modify the following variables
set "yearDay="
set "fileList="
md %out_path%
md %proc_path%
::Process all *.tif files in input path
cd /d "%in_path%"
for %%a in (*.tif) do (
set "fileName=%%a"
if %1 == 001-031 goto :condition1 ::reg/leap
if %2 == 032-059 goto :condition2 ::reg
if %3 == 032-060 goto :condition2 ::leap
if %4 == 060-090 goto :condition3 ::reg
if %5 == 061-091 goto :condition3 ::leap
if %6 == 091-120 goto :condition4 ::reg
if %7 == 092-121 goto :condition4 ::leap
if %8 == 121-151 goto :condition5 ::reg
if %9 == 122-152 goto :condition5 ::leap
if %10 == 152-181 goto :condition6 ::reg
if %11 == 153-182 goto :condition6 ::leap
if %12 == 182-212 goto :condition7 ::reg
if %13 == 183-213 goto :condition7 ::leap
if %14 == 213-243 goto :condition8 ::reg
if %15 == 214-244 goto :condition8 ::leap
if %16 == 244-273 goto :condition9 ::reg
if %17 == 245-274 goto :condition9 ::leap
if %18 == 274-304 goto :condition10 ::reg
if %19 == 275-305 goto :condition10 ::leap
if %20 == 305-334 goto :condition11 ::reg
if %21 == 306-335 goto :condition11 ::leap
if %22 == 335-365 goto :condition12 ::reg
if %23 == 336-366 goto :condition12 ::leap
:condition1
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_jan.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition2
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_feb.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition3
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_mar.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition4
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_apr.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition5
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_may.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition6
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_june.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition7
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition8
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_aug.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition9
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_sep.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition10
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_oct.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition11
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_nov.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:condition12
gdal_calculate --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList! --calc="((one-two)/(one+two))" --two=%two_path%\two_abc_dec.tif --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList! --extent=INTERSECT
goto end
:: Move processed files to a different directory
for %%a in (!fileList!) do move %%a "%proc_path%" >nul
答案1
以下批处理脚本会不递归地浏览文件夹????????*.tif
中模板的所有文件。输入时,文件名的第 2 到第 8 个字符表示模式的儒略日期。浏览文件取决于问题和其他注释中指定的其他条件。%in_path%
YearDay
yyyyddd
- 首先,
%in_path%
浏览文件夹以创建 s 列表YearDay
:参见初始for %%Q
循环;然后 - 每个都
YearDay
在外for %%p
循环中处理,作为副作用,计算常见的格式的日期yyyy-mmm-dd
; - 在内部“for %%G”循环中分开处理相同的文件
YearDay
,并填写文件列表(相同YearDay
); - 一旦内循环结束,最后提到的列表就完成了。
代码
@ECHO OFF >NUL
@SETLOCAL enableextensions enabledelayedexpansion
set "in_path=E:\Proc\Mer"
set "out_path=E:\Proc\Abcde"
set "two_path=E:\Proc\Me"
set "proc_path=E:\Proc\Proc_Mer_Fi"
md %in_path% 2> NUL
md %out_path% 2> NUL
md %two_path% 2> NUL
md %proc_path% 2> NUL
pushd "%in_path%\"
set "yearDay="
set "fileName="
::Get list of all YearDays in input path
set "yearDayList=x"
for /F "tokens=* delims=" %%Q in ('dir /B ????????*.tif') do (
set "fileName=%%Q"
set "yearDay=!fileName:~1,7!"
Call :ItemToList !yearDayList! !yearDay!
)
@set yearDayList=%yearDayList:x= %
@echo yearDayList=%yearDayList%
::Process all *.tif files in input path day by day
for %%p in ( %yearDayList%) Do (
set "yearDay=%%p"
@echo .
set /A "julYr=!yearDay:~0,4!"
set "julDayS=!yearDay:~4,3!"
set "month="
set "monthDay="
rem avoid octal conversions
if "!julDayS:~0,2!"=="00" (
set /A "julDn=!julDayS:~2,1!"
) else (
if "!julDayS:~0,1!"=="0" (
set /A "julDn=!julDayS:~1,2!"
) else (
set /A "julDn=!julDayS!"
)
)
call :months !julYr! !julDn!
set "mDay2=0!monthDay!"
set "mDay2=!mDay2:~-2!"
@echo p^: yearDay !yearDay! yyyy-mmm-dd !julYr!-!month!-!mDay2!
@rem p^: yearDay !yearDay! yyyy-mmm-d !julYr!-!month!-!monthDay!
rem Process all *.tif files of the same YearDay in input path
set "fileList="
for /F "tokens=* delims=" %%G in ('dir /B "?%%p*.tif"') do (
set "fileName=%%G"
set "fileList=!fileList!!fileName! "
@echo G^: !fileName!
)
REM @echo fileList=!fileList!
REM @echo Move processed files ^(one day^) to a different directory
REM for %%a in (!fileList!) do (
REM @echo move %%a "%proc_path%\"
REM )
)
popd
goto :allcommon
:allcommon
@ENDLOCAL
@goto :eof
:ItemToList
rem yearDayList yearDay
SETLOCAL enableextensions enabledelayedexpansion
set "myYDList=%1"
set "myYearDay=%2"
set "myYList="
call :myset "myYList=%%myYDList:%myYearDay%=%%"
if "%myYList%"=="%myYDList%" set "myYDList=%myYDList%x%myYearDay%"
ENDLOCAL & set "yearDayList=%myYDList%"
exit /B
:months
rem %1=julYr
rem %2=julDn
@SETLOCAL enableextensions enabledelayedexpansion
set "mymonth=XXX"
set /a "dayom=%2"
set "allmonths=Xjanfebmaraprmayjunjulaugsepoctnovdec"
set /a "ii=1"
rem leap year test makes use of integer only arithmetic
set /A "yearModi=(%1/4)*4"
If "%1"=="%yearModi%" (
rem leap year
set "daycounts=32 61 92 122 153 183 214 245 275 306 336 367"
) Else (
rem non-leap year
set "daycounts=32 60 91 121 152 182 213 244 274 305 335 366"
)
For %%G in (%daycounts%) do (
if %2 lss %%G (
call :myset "mymonth=%%allmonths:~!ii!,3%%"
rem set /a "dayom+=1"
goto :commmonths
)
set /a ii=!ii!+3
set /a "dayom=%2-%%G+1"
)
:commmonths
ENDLOCAL & (set "month=%mymonth%"
set "monthDay=%dayom%")
exit /B
:myset
rem procedure to set indirect variable replace/substring
rem i.e. dynamic %StrToFind% instead of literal StrToFind
rem common: set "varNew=%varOld:StrToFind=NewStr%"
rem call :myset "varNew=%%varOld:%varToFind%=NewStr%%"
rem call :myset "varNew=%%varOld:!varToFind!=NewStr%%"
rem applicable to %NewStr% as well
rem i.e. dynamic %CharsToSkip% instead of literal CharsToSkip
rem common: set "varNew=%varOld:~CharsToSkip,chars_to_keep%"
rem call :myset "varNew=%%varOld:~%CharsToSkip%,chars_to_keep%%"
rem call :myset "varNew=%%varOld:~!CharsToSkip!,chars_to_keep%%"
rem applicable to %chars_to_keep% as well
set %1
exit /B
有一些(罕见脚本中使用的代码可读性和规则:
- 一些程序以
ENDLOCAL & set "globalVar=%localVar%"
;结尾,通过将ENDLOCAL & SET
命令放在一行,我们能够SET
在命令结束本地化之前访问一个变量ENDLOCAL
; :ItemToList
当且仅当不存在时,程序才将传递给第一个参数的第二个参数连接起来;仅在完整列表中,不常见的x
分隔符才会被常见的分隔符替换;space
- 过程
:months
返回闰年/非闰年的短月份名称和月份中的日期数;输入参数是年份和朱利安日數; - 设置间接变量替换/子串所涉及的过程;由代码中的 s
:myset
自我解释;rem
avoid octal conversions
注意循环内的代码片段for %%p
;有点复杂,因为当以零为前缀时,命令解释器会将数值视为八进制......- 注意所有一致地
SETLOCAL
与ENDLOCAL
和pushd
与popd
- 如果
()
括号跨越多行代码块,则每个)
结束括号在新行上缩进到与相应关键字相同的列,for
或if
除外else
被视为其一部分的if
; - 作为一般原则,所有路径都定义为没有尾随反斜杠;
\
当路径为用过的如果有必要
答案2
代码如下:所有move
s 都回显,所有原始gdal_calculate
调用都替换为,!month!
等等。结果回显为五行,每行 = 一个。有些似乎有点奇怪,特别是那些包含(增长)jan
feb
gdal_calculate
--parameter
!fileList!
@ECHO OFF >NUL
@SETLOCAL enableextensions enabledelayedexpansion
set "in_path=E:\Proc\Mer\"
set "out_path=E:\Proc\Abcde"
set "two_path=E:\Proc\Me\"
set "proc_path=E:\Proc\Proc_Mer_Fi\"
set "yearDay="
set "fileList="
set "fileName="
md %in_path% 2> NUL
md %out_path% 2> NUL
md %two_path% 2> NUL
md %proc_path% 2> NUL
::Process all *.tif files in input path
pushd "%in_path%"
for %%G in (*.tif) do (
set "fileName=%%G"
set "yearDay=!fileName:~1,7!"
set /A "julYr=!fileName:~1,4!"
set "julDayS=!fileName:~5,3!"
set "month="
rem avoid octal conversions
if "!julDayS:~0,2!"=="00" (
set /A "julDn=!julDayS:~2,1!"
) else (
if "!julDayS:~0,1!"=="0" (
set /A "julDn=!julDayS:~1,2!"
) else (
set /A "julDn=!julDayS!"
)
)
call :months !julYr! !julDn!
set "fileList=!fileList!!fileName! "
@echo .
@echo !fileName! yearDay=!yearDay! julYr=!julYr! julDn=!julDn! month=!month!
rem next lines display original gdal_calculate call
rem each line = one --parameter
rem some seem to be quite bit weird
rem in particular those containing !fileList!
@rem echo gdal_calculate
@echo --outfile=%out_path%\Abcde!yearDay!.Q_WER.Tera.tif !fileList!
@echo --calc="((one-two)/(one+two))"
@echo --two=%two_path%\two_abc_!month!.tif
@echo --one=%in_path%\A!yearDay!.Q_WER.Tera.tif !fileList!
@echo --extent=INTERSECT
)
rem Move processed files to a different directory
for %%a in (%fileList%) do @echo move %%a "%proc_path%"
goto :allcommon
:allcommon
popd
@ENDLOCAL
@goto :eof
:months
rem %1=julYr
rem %2=julDn
@SETLOCAL enableextensions enabledelayedexpansion
set "mymonth=XXX"
set "allmonths=Xjanfebmaraprmayjunjulaugsepoctnovdec"
set /a "ii=1"
rem leap year test makes use of integer only arithmetic
set /A "yearReal=%1"
set /A "yearModi=(%yearReal%/4)*4"
If "%yearReal%"=="%yearModi%" (
rem leap year
set "daycounts=32 61 92 122 153 183 214 245 275 306 336 366"
) Else (
rem non-leap year
set "daycounts=32 60 91 121 152 182 213 244 274 305 335 365"
)
rem echo %daycounts% "%yearReal%" "%yearModi%"
For %%G in (%daycounts%) do (
if %2 lss %%G (
call :myset "set mymonth=%%allmonths:~!ii!,3%%"
goto :commonmonths
)
set /a ii=!ii!+3
)
:commonmonths
ENDLOCAL & set month=%mymonth%
exit /B
:myset
%~1
exit /B