标题: [文本处理] 批处理如何计算时间差? [打印本页]
作者: 娜美 时间: 2023-3-19 13:27 标题: 批处理如何计算时间差?
本帖最后由 娜美 于 2023-3-20 17:24 编辑
UTF-8 编码文本
a.txt
使用b文本的上下2行数字去循环查找a文本中第3列的上下行数字顺序是否匹配
如, 在b文本的上下2行为1组数字, 用空行分隔视为1组,
如下面1 2去循环匹配a文本中第3列的上下行是否为1 2
再用另一个2 3去循环匹配a文本中第3列的上下行是否为2 3
如果a文本第3列可以匹配到b文本的上下2行数字 , 而且他们时间相同, 测返回 OK , 如果他们时间不相同, 则需要计算出他们的时间间隔, 精度单位为 秒
b.txt
Thanks
移步原文件下载
https://wwkt.lanzoul.com/iq9h80qies0h
作者: 77七 时间: 2023-3-19 19:27
本帖最后由 77七 于 2023-3-19 19:42 编辑
- @echo off
- rem 文件夹不要存在 1.txt 2.txt
- setlocal enabledelayedexpansion
- for /f "tokens=1-4 delims= " %%a in (a.txt) do (
- if defined str (
- >>1.txt echo !str!#%%a#%%b@%%c##%%d
- set "str=%%a#%%b@@%%c##%%d"
- ) else (
- set "str=%%a#%%b@@%%c##%%d"
- )
- )
- set str=
- for /f "delims=" %%a in (b.txt) do (
- if defined str (
- >>2.txt echo !str! %%a
- set str=
- ) else (
- set "str=%%a"
- )
- )
- endlocal
- setlocal enabledelayedexpansion
- for /f "tokens=1-2" %%a in (2.txt) do (
- for /f "tokens=2,6 delims=中#" %%c in ('type "1.txt" ^| findstr "@@%%a" ^| findstr "@%%b"') do (
- set "t1=%%c"
- set "t2=%%d"
- set "t1=!t1:Mar=3!"
- set "t2=!t2:Mar=3!"
- rem 如果需要可以把12个月份的英文都替换为数字
- for /f "tokens=1-4 delims=,. " %%i in ("!t1!") do (
- set "t1date=%%k-%%i-%%j %%l"
- )
- for /f "tokens=1-4 delims=,. " %%i in ("!t2!") do (
- set "t2date=%%k-%%i-%%j %%l"
- )
- if "!t1date!" equ "!t2date!" (
- echo 计算列%%a%%b 时差间隔: OK
- ) else if "!t1date!" gtr "!t2date!" (
- call :t "!t2date!" "!t1date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- ) else (
- call :t "!t1date!" "!t2date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- )
- )
- )>>c2.txt
- endlocal
- pause
- exit
-
- :t
- ::日期时间差 code by foxjl
- rem set /p date1=输入开始日期(如1984-2-22 5:11:3):
- rem set /p date2=输入结束日期(如2013-9-18 5:6:31):
- set date1=%~1
- set date2=%~2
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date1%") do ((set Y1=%%i) && (set M1=%%j) && (set D1=%%k) && (set H1=%%l) && (set F1=%%m) && (set S1=%%n) && (set MS1=%%o))
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date2%") do ((set Y2=%%i) && (set M2=%%j) && (set D2=%%k) && (set H2=%%l) && (set F2=%%m) && (set S2=%%n) && (set MS2=%%o))
- set /a secs=((d2-32075+1461*(y2+4800+(m2-14)/12)/4+367*(m2-2-(m2-14)/12*12)/12-3*((y2+4900+(m2-14)/12)/100)/4)*86400+H2*3600+F2*60+S2)-((d1-32075+1461*(y1+4800+(m1-14)/12)/4+367*(m1-2-(m1-14)/12*12)/12-3*((y1+4900+(m1-14)/12)/100)/4)*86400+H1*3600+F1*60+S1)
- rem set /a D=secs/86400,H=(secs%%86400)/3600,M=(secs%%3600)/60,S=secs%%60
- rem echo.&echo.%date1%与%date2%之间相隔:%D%天%H%时%M%分%S%秒
- rem echo %secs%
- exit /b
复制代码
试试这样行吗?字符串比较不太熟悉,很多地方不知道写的对不对
作者: 77七 时间: 2023-3-19 19:30
如果a.txt里的**表示的内容不确定,可以预先处理一遍,删除掉
作者: 娜美 时间: 2023-3-19 20:36
本帖最后由 娜美 于 2023-3-20 17:21 编辑
@77七 Thanks
偿试执行了一下- @echo off
- rem 文件夹不要存在 1.txt 2.txt
- setlocal enabledelayedexpansion
- for /f "tokens=1-4 delims= " %%a in (a.txt) do (
- if defined str (
- >>1.txt echo !str!#%%a#%%b@%%c##%%d
- set "str=%%a#%%b@@%%c##%%d"
- ) else (
- set "str=%%a#%%b@@%%c##%%d"
- )
- )
- set str=
- for /f "delims=" %%a in (b.txt) do (
- if defined str (
- >>2.txt echo !str! %%a
- set str=
- ) else (
- set "str=%%a"
- )
- )
- endlocal
- setlocal enabledelayedexpansion
- for /f "tokens=1-2" %%a in (2.txt) do (
- for /f "tokens=2,6 delims=中#" %%c in ('type "1.txt" ^| findstr "@@%%a" ^| findstr "@%%b"') do (
- set "t1=%%c"
- set "t2=%%d"
- set "t1=!t1:Mar=3!"
- set "t2=!t2:Mar=3!"
- rem 如果需要可以把12个月份的英文都替换为数字
- for /f "tokens=1-4 delims=,. " %%i in ("!t1!") do (
- set "t1date=%%k-%%i-%%j %%l"
- )
- for /f "tokens=1-4 delims=,. " %%i in ("!t2!") do (
- set "t2date=%%k-%%i-%%j %%l"
- )
- if "!t1date!" equ "!t2date!" (
- echo 计算列%%a%%b 时差间隔: OK
- ) else if "!t1date!" gtr "!t2date!" (
- call :t "!t2date!" "!t1date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- ) else (
- call :t "!t1date!" "!t2date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- )
- )
- )>>c2.txt
- endlocal
- pause
-
- :t
- ::日期时间差 code by foxjl
- rem set /p date1=输入开始日期(如1984-2-22 5:11:3):
- rem set /p date2=输入结束日期(如2013-9-18 5:6:31):
- set date1=%~1
- set date2=%~2
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date1%") do ((set Y1=%%i) && (set M1=%%j) && (set D1=%%k) && (set H1=%%l) && (set F1=%%m) && (set S1=%%n) && (set MS1=%%o))
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date2%") do ((set Y2=%%i) && (set M2=%%j) && (set D2=%%k) && (set H2=%%l) && (set F2=%%m) && (set S2=%%n) && (set MS2=%%o))
- set /a secs=((d2-32075+1461*(y2+4800+(m2-14)/12)/4+367*(m2-2-(m2-14)/12*12)/12-3*((y2+4900+(m2-14)/12)/100)/4)*86400+H2*3600+F2*60+S2)-((d1-32075+1461*(y1+4800+(m1-14)/12)/4+367*(m1-2-(m1-14)/12*12)/12-3*((y1+4900+(m1-14)/12)/100)/4)*86400+H1*3600+F1*60+S1)
- rem set /a D=secs/86400,H=(secs%%86400)/3600,M=(secs%%3600)/60,S=secs%%60
- rem echo.&echo.%date1%与%date2%之间相隔:%D%天%H%时%M%分%S%秒
- rem echo %secs%
- exit /b
复制代码
格式基本正确, 只是计算时间差秒数结果值不准确
如果忽略年月日, 是否会可以计算出正确时间差秒数 ?
例如
年月日可以忽略他们不处理, 仅需要对时间组处理是否会简单一些 ?
只需要计算他们时间差 年月日可以忽略
有星号这一列完全可以忽略他们, 因为它在最后一列, 对处理数据应该没有影响
作者: idwma 时间: 2023-3-19 21:08
- #@&cls&powershell -sta "gc '%~f0'|out-string|iex"&pause&exit
- $a=(gc -enc utf8 a.txt) -join "`n"
- (gc b.txt) -join "`n" -split "`n`n"|%{
- $b=$_ -split "`n"
- [regex]::matches($a,'(^|\n)[^\t]+\t([^\t]+)\s\S+\t' + $b[0] + '[^\n]+\1[^\t]+\t([^\t]+)\s\S+\t' + $b[1])|%{
- $c=[datetime]$_.Groups[3].value-[datetime]$_.Groups[2].value
- if($c.seconds -eq 0){
- "计算列: {0}{1}`t`t时差间隔: {2}" -f $b[0],$b[1],'OK'
- }else{
- "计算列: {0}{1}`t`t时差间隔: {2}秒" -f $b[0],$b[1],$c.seconds
- }
- ''
- }
- }|sc c.txt
复制代码
作者: 娜美 时间: 2023-3-19 21:50
本帖最后由 娜美 于 2023-3-20 17:20 编辑
回复 5# idwma
@idwma 哥哥的比较简单直接 格式及计算秒数基本正确 Good
但如果是这样结构似乎会多计算一些重复行, 似乎是最后一列如果是数字2或3 会影响到处理数据
请注意: 复制以下数据到文本后某些列tab键符变成空格, 需要将分隔符还原到样本格式处理
如果可以希望可以批量同时处理多个文件, 处理后的和原文件名称相同, 只是在后面增加txt后辍即可 Thanks idwma 哥哥
作者: idwma 时间: 2023-3-19 22:18
本帖最后由 idwma 于 2023-3-19 22:20 编辑
回复 6# 娜美
第五行改一下
[regex]::matches($a,'(^|\n)[^\t]+\t([^\t]+)\s\S+\t' + $b[0] + '[^\n]+\1[^\t]+\t([^\t]+)\s\S+\t' + $b[1] + '[^\n]+‘)
多个文件是什么样的
作者: 77七 时间: 2023-3-19 22:23
回复 4# 娜美
2楼代码实测把a.txt保存为ansi可以得到正确结果可能我用了 汉字作为分隔符,出现了问题,现修改如下,应该支持utf-8了
将第24行改为- for /f "tokens=2,6 delims=.#" %%c in ('type "1.txt" ^| findstr "@@%%a" ^| findstr "@%%b"') do (
复制代码
作者: terse 时间: 2023-3-19 22:48
本帖最后由 terse 于 2023-3-20 16:13 编辑
纯P
修改关于时间的算法,现在按1970.1.1的时间为基数,之前的可能出错- @echo off&setlocal enabledelayedexpansion
- rem 存为ANSI码
- set /a "Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12"
- set "d=(36525*(y+4716)/100+306001*(m+1)/10000+10%%%%b%%100-2442125)"
- set "s=(10%%d%%100)*3600+(10%%e%%100)*60+(10%%f%%100)"
- set "bs=#"
- for /f "delims=" %%i in (b.txt) do (
- if defined b (
- set bs=!bs!!b!%%i#
- set "b="
- ) else set b=%%i
- )
- for /f "delims=" %%f in ('dir /b /a-d *.txt') do (
- (for /f "usebackq tokens=2,3,5 delims= ,." %%a in ("%%f") do (
- for %%i in ("!a!%%c") do if not "!bs!" == "!bs:#%%~i#=!" (
- if not "!str!" == "%%a%%b" (
- set t=0
- for %%m in ("%%a%%b" "!str!" ) do (
- for /f " tokens=1-6 delims=: " %%a in (%%m) do (
- set /a "m=(%%a+9)%%12+3,y=%%c-m/13"
- if !t! == 0 (
- set /a "t=%d%*86400+%s%"
- ) else set /a "t-=%d%*86400+%s%"
- )
- )
- echo;计算列: !a!%%c 时差间隔: !t!秒
- ) else echo;计算列: !a!%%c 时差间隔: OK
- )
- set "a=%%c"
- set "str=%%a%%b"
- ))>%%f.tmp
- )
- pause
复制代码
作者: 77七 时间: 2023-3-19 22:49
回复 4# 娜美
我重新贴一遍吧,把*那列忽略掉,如果含有@#.都会有影响,我是把两行合并成一行了- @echo off
- rem 文件夹不要存在 1.txt 2.txt
- setlocal enabledelayedexpansion
- for /f "tokens=1-4 delims= " %%a in (a.txt) do (
- if defined str (
- >>1.txt echo !str!#%%a#%%b@%%c##1
- set "str=%%a#%%b@@%%c##1"
- ) else (
- set "str=%%a#%%b@@%%c##1"
- )
- )
- set str=
- for /f "delims=" %%a in (b.txt) do (
- if defined str (
- >>2.txt echo !str! %%a
- set str=
- ) else (
- set "str=%%a"
- )
- )
- endlocal
- setlocal enabledelayedexpansion
- for /f "tokens=1-2" %%a in (2.txt) do (
- for /f "tokens=2,6 delims=.#" %%c in ('type "1.txt" ^| findstr "@@%%a" ^| findstr "@%%b"') do (
- set "t1=%%c"
- set "t2=%%d"
- set "t1=!t1:Mar=3!"
- set "t2=!t2:Mar=3!"
- rem 如果需要可以把12个月份的英文都替换为数字
- for /f "tokens=1-4 delims=,. " %%i in ("!t1!") do (
- set "t1date=%%k-%%i-%%j %%l"
- )
- for /f "tokens=1-4 delims=,. " %%i in ("!t2!") do (
- set "t2date=%%k-%%i-%%j %%l"
- )
- if "!t1date!" equ "!t2date!" (
- echo 计算列%%a%%b 时差间隔: OK
- ) else if "!t1date!" gtr "!t2date!" (
- call :t "!t2date!" "!t1date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- ) else (
- call :t "!t1date!" "!t2date!"
- echo 计算列%%a%%b 时差间隔: !secs!秒
- )
- )
- )>>c2.txt
- endlocal
- pause
- exit
-
- :t
- ::日期时间差 code by foxjl
- rem set /p date1=输入开始日期(如1984-2-22 5:11:3):
- rem set /p date2=输入结束日期(如2013-9-18 5:6:31):
- set date1=%~1
- set date2=%~2
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date1%") do ((set Y1=%%i) && (set M1=%%j) && (set D1=%%k) && (set H1=%%l) && (set F1=%%m) && (set S1=%%n) && (set MS1=%%o))
- for /f "tokens=1,2,3,4,5,6,7 delims=-/:. " %%i in ("%date2%") do ((set Y2=%%i) && (set M2=%%j) && (set D2=%%k) && (set H2=%%l) && (set F2=%%m) && (set S2=%%n) && (set MS2=%%o))
- set /a secs=((d2-32075+1461*(y2+4800+(m2-14)/12)/4+367*(m2-2-(m2-14)/12*12)/12-3*((y2+4900+(m2-14)/12)/100)/4)*86400+H2*3600+F2*60+S2)-((d1-32075+1461*(y1+4800+(m1-14)/12)/4+367*(m1-2-(m1-14)/12*12)/12-3*((y1+4900+(m1-14)/12)/100)/4)*86400+H1*3600+F1*60+S1)
- rem set /a D=secs/86400,H=(secs%%86400)/3600,M=(secs%%3600)/60,S=secs%%60
- rem echo.&echo.%date1%与%date2%之间相隔:%D%天%H%时%M%分%S%秒
- rem echo %secs%
- exit /b
复制代码
作者: 娜美 时间: 2023-3-20 00:05
本帖最后由 娜美 于 2023-3-20 00:09 编辑
@terse @idwma @77七 都ok哦 thanks
现有350个文件需要处理, 一个一个处理感觉挺麻烦, 想批量同时处理多个文件, 各个文件数据格式都相同, 处理后文件名需要和原文件名称相同,
如
a.txt
2.txt
处理好的各个文件后缀用tmp就行
a.txt.tmp
2.txt.tmp
作者: terse 时间: 2023-3-20 15:55
回复 11# 娜美
已修改 另外处理时间换个算法 原来的怕有误
作者: 娜美 时间: 2023-3-20 17:18
回复 12# terse
Good 多谢哥哥
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |