O script em lote abaixo procura todos os arquivos de um modelo ????????*.tif
na pasta %in_path%
sem recursão. Por entrada, os caracteres de 2 a 8 do nome do arquivo indicam a data juliana YearDay
do padrão yyyyddd
. Percorrer os arquivos determinados por outras condições especificadas na pergunta e comentários adicionais.
- primeiro, a pasta
%in_path%
navegou para criar uma lista deYearDay
s: veja a inicialfor %%Q
loop; então - cada
YearDay
processado em um loopfor %%p
externo, onde, como efeito colateral, é calculada a data comum do formatoyyyy-mmm-dd
; - arquivos do mesmo
YearDay
processados separadamente em um loop interno 'para %% G' e há uma lista de arquivos (o mesmoYearDay
) preenchidos; - a última lista mencionada é concluída assim que o loop interno terminar.
O código
@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
Existem algumas técnicas comuns e regras de legibilidade do código usadas no script:
- alguns procedimentos terminam em
ENDLOCAL & set "globalVar=%localVar%"
; colocando os comandosENDLOCAL & SET
em uma única linha, conseguimosSET
a variável imediatamente antes que a localização seja finalizada pelo comandoENDLOCAL
; - o procedimento
:ItemToList
concatena o segundo parâmetro passado para o final do primeiro parâmetro se, e somente se, não estiver presente lá;x
delimitador incomum é substituído pelospace
comum apenas na lista completa; - o procedimento
:months
retorna o nome do mês abreviado e o número do dia no mês com relação ao ano bissexto / não-bissexto; os parâmetros de entrada são ano e juliano número do dia; - procedimento
:myset
envolvido para definir substituição de variável indireta / substring; auto-explicado porrem
s no código; - anote um trecho de código intitulado
avoid octal conversions
dentro dofor %%p
loop; um pouco complicado, como valores numéricos teriam considerado octal pelo interpretador de comandos quando prefixado por zero ... - observe todos os
SETLOCAL
combinados de forma consistente comENDLOCAL
epushd
compopd
- se
()
parênteses abrangerem um bloco de código de várias linhas, todos os)
final parênteses serão recuados em uma nova linha para a mesma coluna que a palavra-chave correspondentefor
ouif
excetoelse
, que é contado como uma parte deif
; - todos os caminhos são, por princípio geral, definidos com sem barra invertida ; adicione a barra invertida
\
quando um caminho é usado se necessário