У меня есть множество изображений из каталога, который необходимо вычесть из другого изображения (другого каталога), и я не знаю, как сделать это автоматически в пакетном процессе. Любая идея?

Ниже приведены цели для командного файла:

  • Создать выходной каталог
  • Создать каталог 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

2 ответа2

1

Ниже пакетный скрипт просматривает все файлы ????????*.tif в папке %in_path% без рекурсии. По записи YearDay -й символ имени файла указывает юлианскую дату YearDay шаблона yyyyddd . Просмотр файлов определяется дальнейшими условиями, указанными в вопросе и дополнительными комментариями.

  • сначала просматривается папка %in_path% для создания списка YearDay s: см. исходную информацию для цикла for %%Q ; затем
  • каждый YearDay обрабатывается во внешнем цикле for %%p где в качестве побочного эффекта вычисляется общая дата в формате yyyy-mmm-dd ;
  • файлы одного и того же YearDay обрабатываются отдельно во внутреннем цикле 'for %% G' и заполняется список файлов (того же 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 возвращают короткое название месяца и номер дня в месяце относительно високосного / не високосного года; входными параметрами являются год и номер юлианского дня;
  • процедура :myset используется для установки косвенной переменной replace / substring; самоочевидный rem в коде;
  • обратите внимание на фрагмент кода во avoid octal conversions в цикле for %%p ; немного сложнее, так как числовые значения считались бы восьмеричными для интерпретатора команд, если им предшествовал ноль ...
  • обратите внимание на все последовательно связанные SETLOCAL с ENDLOCAL и pushd с popd
  • если () круглые скобки охватывают кодовый блок из нескольких строк, то ) заканчивается скобка отступом на новой линии к той же самой колонке , как соответствующее ключевое слово for или if , кроме else , что считается как часть if
  • все пути, по общему принципу, определены без обратной косой черты ; добавьте \ обратную косую черту, когда путь используется при необходимости
0

Вот код: все 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .