标题: [文本处理] 求助批处理从文件夹中比对新增的xml文件时间戳,然后拷贝文件,求帮忙优化脚本。 [打印本页]
作者: licunwei 时间: 2024-5-27 15:07 标题: 求助批处理从文件夹中比对新增的xml文件时间戳,然后拷贝文件,求帮忙优化脚本。
本帖最后由 licunwei 于 2024-5-27 18:03 编辑
以下脚本是通过比对D:\SCETC\dataXml\路径下最新的*602和*603文件时间戳,如果2个文件的修改时间在1秒内,不执行任何动作。如果大于1秒就拷贝*603文件。我用了goto循环,虽然可以比对,但还是经常把2个文件 修改时间在1秒内的*603拷贝走了,我打算后面超过1秒的就拷贝后删除源文件,但现在测试都经常出错,更不敢添加删除命令了。求大神帮忙优化优化。
下面是当前脚本,求优化。- @echo off
- if "%1"=="hide" goto :ExecBat
- start mshta vbscript:createobject("wscript.shell").run("""%~f0"" hide",0)(window.close) && exit /b
- :ExecBat
- setlocal enabledelayedexpansion
- set "folder=D:\SCETC\dataXml\"
- set timestamp_602=0
- set timestamp_603=0
- set /a m=0
- set /a n=0
-
- for /F %%a in ('dir /b /s /o-d %folder%*602.xml') do (
- set /a m+=1
- set "timestamp_602!m!=%%~ta"
- )
-
- for /F %%b in ('dir /b /s /o-d %folder%*603.xml') do (
- set /a n+=1
- set "timestamp_603!n!=%%~tb"
- )
-
- set timestamp_602_hh=!timestamp_6021:~11,2!
- set timestamp_602_nn=!timestamp_6021:~14,2!
- set timestamp_602_formatted=!timestamp_602_hh!!timestamp_602_nn!
-
- set timestamp_603_hh=!timestamp_6031:~11,2!
- set timestamp_603_nn=!timestamp_6031:~14,2!
- set timestamp_603_formatted=!timestamp_603_hh!!timestamp_603_nn!
-
- set var602=!timestamp_602_formatted:~1!
- set var603=!timestamp_603_formatted:~1!
-
- set /a time_diff=%var603% - %var602%
-
- if %time_diff% LSS 1 (
- echo Both *602.xml and *603.xml flow generated within 1 second.
- ) else (
- echo Only *603.xml flow generated within 1 second. Deleting latest *603.xml flow...
- for /F %%c in ('dir /b /o-d %folder%*603.xml') do (
- set latest_flow=%%c
- md D:\交易失败流水\%date:~0,4%%date:~5,2%%date:~8,2% 2>nul
- xcopy /y %folder%%%c D:\交易失败流水\%date:~0,4%%date:~5,2%%date:~8,2%\
- call :end
- )
- )
-
- :end
- choice /t 1 /d y /n>nul
- goto ExecBat
复制代码
作者: 77七 时间: 2024-5-27 18:01
修改时间还是创建时间?
作者: licunwei 时间: 2024-5-27 18:03
回复 2# 77七
修改时间,帖子上弄错了。
作者: 77七 时间: 2024-5-27 20:01
回复 3# licunwei
借助ai写了一条powershell命令,将文件修改时间转换为unix时间戳,精确到毫秒。
使用前先备份。
- @echo off
-
- set "folder=D:\SCETC\dataXml\"
- set "str=.LastWriteTime; $epoch = Get-Date '1970-01-01'; $span = New-TimeSpan -Start $epoch -End $time; $milliseconds = [math]::Round($span.TotalMilliseconds); Write-Output $milliseconds"
- :loop
- setlocal
- for %%x in (602 603) do (
- for /f "delims=" %%i in ('dir /b /s /a-d /od "%folder%\*%%x.xml"') do (
- set file_%%x=%%i
- )
- setlocal enabledelayedexpansion
- for /f "delims=" %%a in ('powershell -Command "$time=(Get-Item '!file_%%x!')%str%"') do (
- endlocal
- set "unix_%%x=%%a"
- )
- )
- if "%unix_602%" geq "%unix_603%" (
- set d=%unix_602%-%unix_603%
- ) else (
- set d=%unix_603%-%unix_602%
- )
- for /f %%a in ('powershell -c "%d%"') do (
- echo 毫秒差 %%a
- if %%a gtr 1000 (
- for /f %%a in ('powershell -c "'{0:yyyyMMdd}' -f (get-date)"') do (
- md "D:\交易失败流水\%%a" 2>nul
- copy "%file_603%" "D:\交易失败流水\%%a"
- del "%file_603%"
- )
- )
- )
- endlocal
- timeout 1
- goto :loop
复制代码
作者: licunwei 时间: 2024-5-27 21:34
回复 4# 77七
谢谢,明天我试试。
作者: ShowCode 时间: 2024-5-28 08:49
回复 1# licunwei - @echo off
- set "folder=D:\SCETC\dataXml\"
- cd /d "%folder%"
- for /f "delims=" %%a in ('dir /b /s /a-d /od *602.xml') do (
- set "File602=%%a"
- )
- for /f "delims=" %%a in ('powershell –NoProfile –ExecutionPolicy Bypass "(Get-ChildItem '%File602%').LastWriteTime"') do (
- set "Time602=%%a"
- )
- for /f "delims=" %%a in ('dir /b /s /a-d /od *603.xml') do (
- set "File603=%%a"
- )
- for /f "delims=" %%a in ('powershell –NoProfile –ExecutionPolicy Bypass "(Get-ChildItem '%File603%').LastWriteTime"') do (
- set "Time603=%%a"
- )
- if "%Time602%" == "%Time603%" (
- echo copy %File603%
- ) else (
- echo not copy
- )
- pause
复制代码
作者: licunwei 时间: 2024-5-28 11:42
回复 4# 77七
老师 还是会经常计算错误,下面是2个文件计算出来的毫秒差,157和171644293519 是同样的2个文件,157是对的,但偶尔会计算错误,误删除文件。
毫秒差 1716442935719
del "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml"
毫秒差 157
毫秒差 157
毫秒差 157
毫秒差 157
毫秒差 157
毫秒差 157
作者: licunwei 时间: 2024-5-28 12:26
回复 4# 77七
等待 0 秒,按一个键继续 ...
C:\Users\Administrator\Desktop>goto :loop
C:\Users\Administrator\Desktop>setlocal
C:\Users\Administrator\Desktop>for %x in (602 603) do (
for /F "delims=" %i in ('dir /b /s /a-d /od "C:\Users\Administrator\Desktop\新建文件夹\\*%x.xml"') do (set file_%x=%i )
setlocal enabledelayedexpansion
for /F "delims=" %a in ('powershell -Command "$time=(Get-Item '!file_%x!').LastWriteTime; $epoch = Get-Date '1970-01-01'; $span = New-TimeSpan -Start $epoch -End $time; $milliseconds = [math]::Round($span.TotalMilliseconds); Write-Output $milliseconds"') do (
endlocal
set "unix_%x=%a"
)
)
C:\Users\Administrator\Desktop>(
for /F "delims=" %i in ('dir /b /s /a-d /od "C:\Users\Administrator\Desktop\新建文件夹\\*602.xml"') do (set file_602=%i )
setlocal enabledelayedexpansion
for /F "delims=" %a in ('powershell -Command "$time=(Get-Item '!file_602!').LastWriteTime; $epoch = Get-Date '1970-01-01'; $span = New-TimeSpan -Start $epoch -End $time; $milliseconds = [math]::Round($span.TotalMilliseconds); Write-Output $milliseconds"') do (
endlocal
set "unix_602=%a"
)
)
找不到文件
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=Get-Item : 无法将参数绑定到参数“Path”,因为该参数为空字符串。"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=所在位置 行:1 字符: 17"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=+ $time=(Get-Item '').LastWriteTime; $epoch = Get-Date '1970-01-01'; $s ..."
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=+ ~~"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= + CategoryInfo : InvalidData: ( [Get-Item],ParameterBindingValidationException"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.GetI "
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= temCommand"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= "
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=New-TimeSpan : 无法将参数“End”绑定到目标。设置“End”时发生异常:“无法将空值转换为类型“System.DateTime”。”"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=所在位置 行:1 字符: 108"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=+ ... e '1970-01-01'; $span = New-TimeSpan -Start $epoch -End $time; $milli ..."
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=+ ~~~~~"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= + CategoryInfo : WriteError: (:) [New-TimeSpan], ParameterBindingException"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.NewTimeSpanCommand"
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602= "
)
C:\Users\Administrator\Desktop>(
endlocal
set "unix_602=0"
)
C:\Users\Administrator\Desktop>(
for /F "delims=" %i in ('dir /b /s /a-d /od "C:\Users\Administrator\Desktop\新建文件夹\\*603.xml"') do (set file_603=%i )
setlocal enabledelayedexpansion
for /F "delims=" %a in ('powershell -Command "$time=(Get-Item '!file_603!').LastWriteTime; $epoch = Get-Date '1970-01-01'; $span = New-TimeSpan -Start $epoch -End $time; $milliseconds = [math]::Round($span.TotalMilliseconds); Write-Output $milliseconds"') do (
endlocal
set "unix_603=%a"
)
)
C:\Users\Administrator\Desktop>(set file_603=C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml )
C:\Users\Administrator\Desktop>(
endlocal
set "unix_603=1716442935719"
)
C:\Users\Administrator\Desktop>if "0" GEQ "1716442935719" (set d=0-1716442935719 ) else (set d=1716442935719-0 )
C:\Users\Administrator\Desktop>for /F %a in ('powershell -c "1716442935719-0"') do (
echo 毫秒差 %a
if %a GTR 200 (for /F %a in ('powershell -c "'{0:yyyyMMdd}' -f (get-date)"') do (
md "D:\交易失败流水\%a" 2>nul
copy "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml" "D:\交易失败流水\%a"
del "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml"
) )
)
C:\Users\Administrator\Desktop>(
echo 毫秒差 1716442935719
if 1716442935719 GTR 200 (for /F %a in ('powershell -c "'{0:yyyyMMdd}' -f (get-date)"') do (
md "D:\交易失败流水\1716442935719" 2>nul
copy "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml" "D:\交易失败流水\1716442935719"
del "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml"
) )
)
毫秒差 1716442935719
C:\Users\Administrator\Desktop>(
md "D:\交易失败流水\20240528" 2>nul
copy "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml" "D:\交易失败流水\20240528"
del "C:\Users\Administrator\Desktop\新建文件夹\S0003510010100101003020240523054215350603.xml"
)
已复制 1 个文件。
C:\Users\Administrator\Desktop>endlocal
C:\Users\Administrator\Desktop>timeout 1
等待 0 秒,按一个键继续 ...
作者: czjt1234 时间: 2024-5-28 12:30
慢一点的电脑,批处理调用powershell可能都不止一秒
建议批处理第一行获取当前时间,后面再对时间进行处理
作者: 77七 时间: 2024-5-28 12:42
回复 8# licunwei
这个是关键的报错信息。
4楼代码10-11行之间增加个判断
- if not defined file_%%x (
- echo file_%%x 文件不存在\其它原因,返回重试
- endlocal
- timeout 1
- goto :loop
- )
复制代码
作者: 77七 时间: 2024-5-28 13:11
回复 9# czjt1234
是的,这是个问题,开始我也想过,频繁调用powershell效率会降低,很可能是刻舟求剑。写出来也是一种参考吧,如果不行,楼主再寻求他法。
作者: hfxiang 时间: 2024-5-28 13:33
回复 1# licunwei
12~15行提取时间方式- for /F %%a in ('dir /b /s /o-d %folder%*602.xml') do (
- set /a m+=1
- set "timestamp_602!m!=%%~ta"
- )
复制代码
set "timestamp_602!m!=%%~ta"不含秒,建议用forfiles,可在命令行窗口中测试一下如下指令然后看能否用得上:- FORFILES /p "D:\SCETC\dataXml" /S /M *60?.xml /C "cmd /c echo @path @fdate @ftime"
复制代码
另:时间计算可参考
http://www.bathome.net/redirect. ... 37235&ptid=2627
作者: licunwei 时间: 2024-5-28 13:54
回复 10# 77七
好的 谢谢 我再测试观察看看。
作者: licunwei 时间: 2024-5-28 13:56
回复 12# hfxiang
谢谢 我试试。
作者: licunwei 时间: 2024-5-28 16:47
回复 9# czjt1234
老师能否按你的思路帮我优化下,谢谢了。
作者: czjt1234 时间: 2024-5-28 20:35
回复 15# licunwei
你到powershell区去问下
因为是循环执行的,所以poweshell不要退出,一直用PS执行所有操作就可以
作者: aloha20200628 时间: 2024-5-29 18:21
回复 1# licunwei
一楼代码用dir简报获取文件时间戳的精度是分钟级
还是用powershell功能获取秒级精度的文件时间戳更方便,只是powershell的首启速度较慢而已...
以下代码假设*603*.xml文件修改时间 ‘总是晚于’ *602*.xml文件修改时间
- @echo off &setlocal enabledelayedexpansion
- set "folder=D:\SCETC\dataXml\"
- :[Loop]
- (call :getSofF "%folder%*602.xml" f602 h602 s602)
- (call :getSofF "%folder%*603.xml" f603 h603 s603)
- if !s602! gtr !s603! set/a "s603+=(24+h603)*3600"
- set/a "dt=!s603!-!s602!"
- if !dt! gtr 1 (xcopy /y /i "!f603!" "D:\交易失败流水\%date:~0,4%%date:~5,2%%date:~8,2%\")
- goto[Loop]
- :getSofF
- for /f "tokens=1* delims=:" %%A in (' dir /b/o-d/tw "%~1"^|findstr /n ".*"^|findstr /lbc:"1:" ') do (
- for /f "delims=" %%t in (' powershell "(Get-ChildItem """%%B""").LastWriteTime" ') do (
- set "t=%%t" &for /f "tokens=1-3 delims=:" %%a in ("!t:~-8!") do for %%k in (%%a %%b %%c) do (
- set "k=%%k" &if "!k:~,1!"=="0" (set "ts=!ts!:!k:~-1!") else set "ts=!ts!:!k!"
- )
- )
- for /f "tokens=1-3 delims=:" %%a in ("!ts:~1!") do (set "%~3=%%a"&set/a "s=%%a*3600+%%b*60+%%c")
- set "%~2=%%B" &set "%~4=!s!"
- )
- exit/b
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |