返回列表 发帖

[文本处理] 批处理或PowerShell计算字段之间的时间

a.txt 是ANSI编码
需要计算出2个字段之间的经过时间,   如果有多个相同"企业 名称" 字段, 计算出从发现有第一个 "企业 名称"  时间  到 "退出" 字段之间的时间过程,   以第一个有 "企业 名称" 时间开始为准
以小时为最大单位
似乎可以用  "企业  名称"  作为匹配字段,      似乎可以把 ">"作为分隔符  因为名称后面会有空格情况  也会有可能存在使用某些符号,  代码尽量不要被名称字符串影响或其他原因而导致有一些没有被计算出

不知道为什么,  发现这个有一些没有被计算到,  现在输出格式也需要改变一下
PowerShell "(gc a.txt) -match '企业\s*名称:|退出' | forEach{if(++$i%%2){$a=$_ -split '>\s*企业\s*名称:'; '企业   > ' + $a[1];}else{$b=$_ -replace '>.*$'; $t=get-Date ([DateTime]$b-[DateTime]$a[0]).Ticks; '时间 > ' + '{0:HH}h:{1:mm}m:{2:ss}s' -f $t,$t,$t;echo '';}}" > b.txtCOPY
计算后,  请使用另一种时间格式拼接显示  使用Tab   即"\t"  分隔符拼接
企业 名称:优 美 利 A 时间: 00h:05m:01s
企业 名称:利海 B 时间: 00h:01m:01sCOPY
因为网页会把"\t"  分隔符变成空格, 所以提供输出格式样本
https://wwkt.lanzoul.com/ifa6C15sw4ne
awk   PowerShell    bat 码 都行

回复 1# 娜美


    我们这个论坛不会把制表符变成空格,你怎么测试的变成空格了?我试试能否重现。
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

本帖最后由 wanghan519 于 2023-8-19 15:10 编辑

powershell写的请小心测试
$d=@{};cat .\a.txt -Encoding oem | ? {$_ -match '\d>\s*(企业|退出)'} | % {$a=$_ -split '>\s*';if($a[1] -match '企业' -and ($a[1] -notin $d.Keys)){$d.Add($a[1],1);$t=Get-Date $a[0];$n=$a[1]};if($a[1] -match '退出'){$tt=(Get-Date $a[0]).Subtract($t);$n+"`t时间:"+$tt.Hours+'h:'+$tt.Minutes+'m:'+$tt.Seconds+'s'}}COPY
粘贴上来没法用,试了好几次发现,因为单引号正好出现在边界处,直接用鼠标选择复制代码粘贴出来居然多一个空格,以前没遇到过。。。

TOP

本帖最后由 77七 于 2023-8-19 19:23 编辑

a.txt
19:33:30 August 16 2023>   企业 名称:优 美 利 A
19:35:30 August 16 2023>   企业 名称:优 美 利 A
19:36:30 August 16 2023>   企业 名称:优 美 利 A
19:37:30 August 16 2023>   企业 名称:优 美 利 A
19:38:31 August 16 2023>   退出
20:37:30 August 16 2023>   企业 名称:利海 B
20:38:31 August 16 2023>   退出 COPY

@echo off
rem 批处理保存为ansi编码格式
setlocal enabledelayedexpansion
for %%a in (January February March April May June July August September October November December) do (
        set /a n+=1
        set %%a=!n!
)
(for /f "useback tokens=1-4*" %%a in ("a.txt") do (
        set str_year=%%d
        if "%%e" neq "退出 " (
                if not defined str_t1 (
                        set str_t1=!str_year:~0,-1!-!%%b!-%%c %%a
                        set str_name=%%e
                )
        ) else (
                set str_t2=!str_year:~0,-1!-!%%b!-%%c %%a
                call :t "!str_t1!" "!str_t2!" "!str_name!"
                set str_t1=
                set str_t2=
        )
))>b.txt
endlocal
pause
exit
        :t
        ::日期时间差 code by foxjl
        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)
        set /a D=secs/86400,H=(secs%%86400)/3600,M=(secs%%3600)/60,S=secs%%60
        set H=0%H%
        set M=0%M%
        set S=0%S%
        echo %~3        时间:        %H:~-2%h:%M:~-2%m:%S:~-2%s
        exit /bCOPY
时间的天数没有转换为小时,有点问题。
bat小白,请多指教!谢谢!

TOP

回复 3# wanghan519

偿试将a文本中内容多复制几遍测验,  似乎会有这样时间

  
企业 名称:利海 B        时间:0h:-58m:-59sCOPY

TOP

回复 2# Batcher


   不好意思脑子有点混乱了  将代码放入代码框是不会变成空格的的

TOP

本帖最后由 娜美 于 2023-8-19 17:00 编辑

回复 4# 77七


   先谢谢了,   但运行过程中会返回如下提示,  有一部分输出,    目前不知道什么原因,  有点慢, 有很多名称没计算到
'CO' 不是内部或外部命令,也不是可运行的程序
'ww' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
'J' 不是内部或外部命令,也不是可运行的程序
或批处理文件。COPY

TOP

回复 6# 娜美


    和网站没有关系,我这次是'企业'这几个字正好在命令窗口的边缘,单引号后面的中文没法在最后一位显示,所以换行了,但我用鼠标选择复制,复制出来的代码变成了' 企业',多了个空格,所以粘贴回去没法运行,以前没遇到过这种问题 。。。

TOP

回复 5# 娜美


    因为没清理字典,导致后面重复的企业名没读取时间,修改了一下
cat .\a.txt -Encoding oem | ? {$_ -match '\d>\s*(企业|退出)'} | % {$a=$_ -split '>\s*';if($a[1] -match '企业' -and $a[1] -ne $n){$t=Get-Date $a[0];$n=$a[1]};if($a[1] -match '退出'){$tt=(Get-Date $a[0]).Subtract($t);$n+"`t时间:"+$tt.Hours+'h:'+$tt.Minutes+'m:'+$tt.Seconds+'s';$n=""}}COPY

TOP

本帖最后由 娜美 于 2023-8-19 17:31 编辑

回复 9# wanghan519

ok

TOP

像下面这样只有两个的,怎么算,还是到“退出”不?
19:36:30 August 16 2023>   企业 名称:优 美 利 A
19:37:30 August 16 2023>   企业 名称:优 美 利 A
19:38:31 August 16 2023>   退出

还有”企业 名称”后面的需要一样不?比如下面,该怎么算

19:37:30 August 16 2023>   企业 名称:优 美 利 A
20:37:30 August 16 2023>   企业 名称:利海 B
20:38:31 August 16 2023>   退出
20:39:30 August 16 2023>   企业 名称:利海 B

TOP

回复 9# wanghan519


   代码没有任何问题,   
  谢谢哥哥

TOP

回复 11# Five66



像这种情况取第一个也行的,  
19:37:30 August 16 2023>   企业 名称:优 美 利 A
20:37:30 August 16 2023>   企业 名称:利海 B
20:39:30 August 16 2023>   企业 名称:利海 B
20:39:30 August 16 2023>   企业 名称:利海 B
20:38:31 August 16 2023>   退出

TOP

返回列表