Board logo

标题: [文本处理] 【已解决】批处理能否截取一短时间内的Log另存为新的Log? [打印本页]

作者: w31575801    时间: 2020-11-23 10:54     标题: 【已解决】批处理能否截取一短时间内的Log另存为新的Log?

如题 批处理能否截取一个Log日志内的某段时间的Log另存为新的Log?

求教 从0:00:00:001~23:59:59:999 中选取一个时间段的怎么用bet指令操作
00:08:37.859 [KEY STATUS] Push Button Back Key

00:08:37.859  [SEQUENCE] Exec Sequence 1
00:08:37.875 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:39.234 [KEY STATUS] Push Button Back Key

00:08:39.250  [SEQUENCE] Exec Sequence 1
00:08:39.265 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:40.359 Esc Key pressed. ( A Stage )
00:08:40.625 RunThread1 [KEY STATUS] Push Button ESC Key

00:08:40.640  [SEQUENCE] Exec Sequence 1
00:08:40.656 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:40.859 Esc Key pressed. ( A Stage )
00:08:42.015 [KEY STATUS] Push Button Back Key

00:08:42.031  [SEQUENCE] Exec Sequence 1
00:08:42.046 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:43.406 [KEY STATUS] Push Button Back Key

00:08:43.421  [SEQUENCE] Exec Sequence 1
00:08:43.437 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:46.078 [KEY STATUS] Push Button Back Key

00:08:46.078  [SEQUENCE] Exec Sequence 1
00:08:46.093 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:47.468 [KEY STATUS] Push Button Back Key

00:08:47.468  [SEQUENCE] Exec Sequence 1
00:08:47.484 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:48.843 [KEY STATUS] Push Button Back Key

00:08:48.859  [SEQUENCE] Exec Sequence 1
00:08:48.875 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316
00:08:50.234 [KEY STATUS] Push Button Back Key

00:08:50.250  [SEQUENCE] Exec Sequence 1
00:08:50.265 #[SEQ1] Inspection Start !! [Model] D705 [S/W Ver : ] [H/W Ver : ] [Script Ver : D705[MP-3-N-FT57]-200316

00:08:51.625  [SEQUENCE] Exec Sequence 2
作者: qixiaobin0715    时间: 2020-11-23 14:58

回复 1# w31575801
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (for /f "tokens=1,* delims= " %%i in (a.log) do (
  4. set var=%%i
  5. set var=!var::=!
  6. if !var! geq 00101133 if !var! leq 00201145 echo %%i %%j
  7. ))>b.log
  8. pause
复制代码

作者: qixiaobin0715    时间: 2020-11-23 15:22

本帖最后由 qixiaobin0715 于 2020-11-23 16:34 编辑

提供信息不全。时间前面应当还有日期?格式?
作者: w31575801    时间: 2020-11-23 18:48

回复 3# qixiaobin0715


    没有日期,只有一个时间
作者: qixiaobin0715    时间: 2020-11-23 18:54

a.log为源文件,b.log为新文件
作者: w31575801    时间: 2020-11-23 19:20

回复 5# qixiaobin0715


    如果目录下有a1,a2,a3,a4多个文件,可以批量提取出来为b1,b2,b3,b4这样的吗
作者: qixiaobin0715    时间: 2020-11-23 20:25

本帖最后由 qixiaobin0715 于 2020-11-24 09:23 编辑

回复 6# w31575801
新文件名为源文件名前加字符#,这样通用一些。
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for %%a in ("*.log") do (
  4.     (for /f "tokens=1,* delims= " %%i in ('type "%%a"') do (
  5.         set var=%%i
  6.         set var=!var::=!
  7.         if !var! geq 00101133 if !var! leq 100201145 echo %%i %%j
  8.     ))>"#%%a"
  9. )
  10. pause
复制代码

作者: w31575801    时间: 2020-11-24 07:16

回复 7# qixiaobin0715


    大佬有个问题,就是当a.log名称中有空格的话提示找不到该log,怎么解决呀
作者: qixiaobin0715    时间: 2020-11-24 08:09

回复 8# w31575801

已修改,试试吧。
作者: w31575801    时间: 2020-11-24 08:38

回复 9# qixiaobin0715


    还是找不到,我删掉空格就可以,大佬能设置个条件直接把空格改成下划线然后在操作截取另存吗,,最后加一个删除原始log只保留修改后的log
作者: qixiaobin0715    时间: 2020-11-24 08:47

回复 10# w31575801
再试试
作者: qixiaobin0715    时间: 2020-11-24 09:34

本帖最后由 qixiaobin0715 于 2020-11-24 09:37 编辑

回复 8# w31575801

经过测试,我这里没问题啊。请不要直接选中代码复制,点击代码下方的“复制代码”,再粘贴。将bat文件另存为编码为ANSI的文件。
作者: w31575801    时间: 2020-11-24 09:57

回复 11# qixiaobin0715


    可以了谢谢大佬
作者: w31575801    时间: 2020-11-24 21:49

回复 11# qixiaobin0715


    大佬有个问题就是当log日志太大的时候转换特别慢,有没有什么方法解决,比如引用notepad+去操作
作者: Batcher    时间: 2020-11-24 21:59

回复 14# w31575801


可以考虑试试第三方命令行工具 sed.exe 或 gawk.exe
http://bcn.bathome.net/s/tool/index.html?key=sed
http://bcn.bathome.net/s/tool/index.html?key=gawk
作者: qixiaobin0715    时间: 2020-11-24 23:01

回复 14# w31575801
EmEditor文本编辑器好像能实现,编写一个宏文件,可能效率较高,家里电脑上没有,明天到单位上看看,很久以前写过宏文件,忘个差不多了,先要熟悉一下,试试吧。
作者: qixiaobin0715    时间: 2020-11-25 06:25

回复 14# w31575801

将7楼代码第4行中type "%%a"改为findstr /b "8: 9: 10: 11:" "%%a",初步筛选一下。
上面是举一个例子,表示筛选的是8~11点的数据,注意时间之间要有空格。这样效率应当高一点。
作者: w31575801    时间: 2020-11-25 09:19

回复 15# Batcher


    大佬 怎么调用呀
作者: flashercs    时间: 2020-11-25 09:30

  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd /d "%~dp0"
  4. set "dtmBegin=00:31:37:501"
  5. set "dtmEnd=14:59:02:999"
  6. for %%A in ("*.log") do (
  7.   >"%%A.log" call :filter "%%A"
  8.   REM >"[%dtmBegin::=;%-%dtmEnd::=;%].%%A" call :filter "%%A"
  9. )
  10. endlocal
  11. pause
  12. exit /b
  13. :filter
  14. set flag=0
  15. for /f "usebackq tokens=1*" %%B in (%1) do (
  16.     set dtm=0%%B
  17.     set dtm=!dtm:~-12!
  18.     REM test the low boundary
  19.     if "!flag!"=="0" (
  20.       if "!dtm!" geq "%dtmBegin%" set flag=1
  21.     )
  22.     REM test the high boundary
  23.     if "!flag!"=="1" (
  24.       if "!dtm!" lss "!dtmEnd!" (
  25.         echo %%B %%C
  26.       ) else (
  27.         set flag=0
  28.         goto next
  29.       )
  30.     )
  31.   )
  32.   :next
  33.   exit /b
复制代码

作者: Batcher    时间: 2020-11-25 09:38

回复 18# w31575801


    请在顶楼提供一段日志文件(不是截图),我来写一下代码。
作者: w31575801    时间: 2020-11-25 10:46

回复 20# Batcher


    已上传 Log日志格式跟这个一样的
作者: w31575801    时间: 2020-11-25 10:51

回复 19# flashercs


    可以直接删掉时间段之前和之后的 比如直接删掉文件8:00之前,17:00之后,不生成新的Log 直接原Log里面修改吗?
作者: Batcher    时间: 2020-11-25 11:58

回复 21# w31575801


截取 11:21:20.367 至 12:13:45.759 之间的内容:
  1. sed -n "/11:21:20\.367/,/12:13:45\.759/p" "1.log" > "2.log"
复制代码

作者: qixiaobin0715    时间: 2020-11-25 13:01

本帖最后由 qixiaobin0715 于 2020-11-25 13:17 编辑

如果会使用EmEditor文本编辑器的话,处理文本的宏文件如下:
  1. editor.ReplaceInFiles( "^00:00:00.001.*\\r\\n((?!09:34:04.989).*\\r\\n)+","",document.Path + "\\*.log", eeFindReplaceRegExp,eeEncodingSystemDefault,"","",eeExFindSeparateCRLF);
  2. editor.ReplaceInFiles( "^09:34:07.247.*\\r\\n(.*\\r\\n)+","",document.Path + "\\*.log", eeFindReplaceRegExp,eeEncodingSystemDefault,"","",eeExFindSeparateCRLF);
复制代码
使用方法:
1.将代码保存为编码为"UTF-16LE”的文件test.jsee。
2.在源文件所在文件夹中新建一个空的txt文件,用EmEditor打开空文件,加载宏文件test.jsee,运行宏文件,即能在源文件上直接修改。
3.第一组数字为首行时间;第二组为保留的开始时间;第三组为保留的终止时间的下一行记录时间。
4.注意备份源文件,加载宏文件后,符合条件的文件夹内的所有.log文件都会被修改。
5.若需要7点之后,9点之前的记录,第二组数字改为07,第三组数字改为09,数字格式应与源文件保持一致,小时数00,01,...10...的格式,不能写成0,1,...,前面的0不能省略。
作者: qixiaobin0715    时间: 2020-11-25 13:48

本帖最后由 qixiaobin0715 于 2020-11-25 19:06 编辑

整点之间的记录要简单点,比如你所说的8~17点,test.jsee:
  1. editor.ReplaceInFiles( "^(0[0-7]|1[7-9]|2[0-3]):.*\\r\\n","",document.Path + "\\*.log", eeFindReplaceRegExp,eeEncodingSystemDefault,"","",eeExFindSeparateCRLF);
复制代码

作者: flashercs    时间: 2020-11-25 14:12

  1. @echo off
  2. setlocal EnableDelayedExpansion
  3. cd /d "%~dp0"
  4. set "dtmBegin=09:31:37:501"
  5. set "dtmEnd=14:59:02:999"
  6. set "file=~%random%~"
  7. for %%A in ("*.log") do (
  8.   >"%file%" call :filter "%%A"
  9.   move /y "%file%" "%%A"
  10.   REM >"[%dtmBegin::=;%-%dtmEnd::=;%].%%A" call :filter "%%A"
  11. )
  12. endlocal
  13. pause
  14. exit /b
  15. :filter
  16. set flag=0
  17. for /f "usebackq tokens=1*" %%B in (%1) do (
  18.     REM test the low boundary
  19.     if "!flag!"=="0" (
  20.       if "%%B" geq "%dtmBegin%" (
  21.           if "%%B" lss "%dtmEnd%" (
  22.             echo %%B %%C
  23.             set flag=1
  24.         ) else (
  25.           goto next
  26.         )
  27.       )
  28.     ) else (
  29.     REM test the high boundary
  30.       if "%%B" lss "%dtmEnd%" (
  31.         echo %%B %%C
  32.       ) else (
  33.         set flag=0
  34.         goto next
  35.       )
  36.     )
  37.   )
  38.   :next
  39.   exit /b
复制代码
回复 22# w31575801
作者: went    时间: 2020-11-25 14:50

本帖最后由 went 于 2020-11-25 15:30 编辑

start开始,end结束,相邻多个开始结束时间只会保存一个
  1. @echo off & cd /d "%~dp0"
  2. set "start=15:40:01.098"
  3. set "end=15:45:45.870"
  4. del *_NEW.log >nul 2>nul
  5. for %%i in ("*.log") do call :splitLog "%%i"
  6. pause&exit
  7. :splitLog
  8. set "start_line=0"
  9. for /f "delims=:" %%a in ('findstr /b /r /n /C:"%start%" "%~1"') do set "start_line=%%a"
  10. set /a "start_line-=1"
  11. if not "%start_line%"=="-1" (
  12. (
  13. for /f "usebackq skip=%start_line% tokens=1*" %%i in ("%~1") do (
  14. echo %%i %%j
  15. if "%%i"=="%end%" goto :done
  16. )
  17. ) > "%~n1_NEW.log"
  18. )
  19. :done
  20. echo %~1 done.
  21. echo -------------------------------------
复制代码
保存多个开始结束时间
  1. @echo off & cd /d "%~dp0"
  2. set "start=15:40:01.098"
  3. set "end=15:45:45.870"
  4. del *_NEW.log >nul 2>nul
  5. for %%i in ("*.log") do call :splitLog "%%i"
  6. pause&exit
  7. :splitLog
  8. set "start_line=0"
  9. for /f "delims=:" %%a in ('findstr /b /r /n /C:"%start%" "%~1"') do set "start_line=%%a" & goto :startDone
  10. :startDone
  11. set /a "start_line-=1"
  12. if not "%start_line%"=="-1" (
  13. (
  14. set "enterEnd=0"
  15. for /f "usebackq skip=%start_line% tokens=1*" %%i in ("%~1") do (
  16. if not "%%i"=="%end%" (
  17. call set /a "1/%%enterEnd%%" >nul 2>nul && goto :done || echo %%i %%j
  18. ) else (
  19. echo %%i %%j
  20. if "%%i"=="%end%" set "enterEnd=1"
  21. )
  22. )
  23. ) > "%~n1_NEW.log"
  24. )
  25. :done
  26. echo %~1 done.
  27. echo -------------------------------------
复制代码

作者: w31575801    时间: 2020-11-26 09:27

回复 19# flashercs


  前面格式发错了 使用之后直接变成0KB 大佬再给改改
作者: w31575801    时间: 2020-11-26 09:29

回复 26# flashercs


直接提示移动了一个文件 然后变成0KB了
作者: w31575801    时间: 2020-11-26 09:32

回复 25# qixiaobin0715


   附件已上传 您再给看看  这个时间段怎么改
作者: w31575801    时间: 2020-11-26 09:33

回复 26# flashercs


    附件已上传 您再给看看编辑一下
作者: flashercs    时间: 2020-11-26 17:28

回复 31# w31575801


    log中还有些行开头不是时间格式,里面还有叹号!
  1. <#*,:&cls
  2. @echo off
  3. pushd "%~dp0"
  4. powershell -NoProfile -ExecutionPolicy RemoteSigned -Command ". ([ScriptBlock]::Create((Get-Content -LiteralPath \"%~0\" -ReadCount 0 | Out-String ))) "
  5. popd
  6. pause
  7. exit /b
  8. #>
  9. # 起始时间
  10. $dtmBegin = "02:31:37.501"
  11. # 终止时间
  12. $dtmEnd = "03:42:00.140"
  13. $logglob = "*.log"
  14. $dtmLength = $dtmBegin.Length
  15. $dtmFormat = "[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9][0-9]"
  16. $buffer = 65536
  17. # utf8-nobom
  18. $encoding = New-Object System.Text.UTF8Encoding -ArgumentList @($false)
  19. foreach ($logfile in (Convert-Path -Path $logglob | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf })) {
  20.   Write-Host $logfile -ForegroundColor Green
  21.   try {
  22.     $stream1 = New-Object System.IO.FileStream -ArgumentList @($logfile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite, $buffer)
  23.     $stream2 = New-Object System.IO.FileStream -ArgumentList @($logfile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write, [System.IO.FileShare]::Read, $buffer)
  24.     $sr = New-Object System.IO.StreamReader -ArgumentList @($stream1, $encoding, $true, $buffer)
  25.     $sw = New-Object System.IO.StreamWriter -ArgumentList @($stream2, $encoding, $buffer)
  26.     $flag = $false
  27.     while (!$sr.EndOfStream) {
  28.       $strLine = $sr.ReadLine()
  29.       $dtmStr = $strLine.Substring(0, [Math]::Min($dtmLength, $strLine.Length))
  30.       if ($dtmStr -notlike $dtmFormat) {
  31.         $sw.WriteLine($strLine)
  32.         continue
  33.       }
  34.       if (!$flag) {
  35.         if ($dtmStr -ge $dtmBegin) {
  36.           if ($dtmStr -lt $dtmEnd) {
  37.             $sw.WriteLine($strLine)
  38.             $flag = $true
  39.           } else {
  40.             break
  41.           }
  42.         }
  43.       } else {
  44.         if ($dtmStr -lt $dtmEnd) {
  45.           $sw.WriteLine($strLine)
  46.         } else {
  47.           $flag = $false
  48.           break
  49.         }
  50.       }
  51.     }
  52.     $sw.Flush()
  53.     $stream2.SetLength($stream2.Position)
  54.   } catch {
  55.     $_ | Write-Host -ForegroundColor Red
  56.   } finally {
  57.     if ($sr) {
  58.       $sr.Dispose()
  59.     }
  60.     if ($sw) {
  61.       $sw.Dispose()
  62.     }
  63.     if ($stream1) {
  64.       $stream1.Dispose()
  65.     }
  66.     if ($stream2) {
  67.       $stream2.Dispose()
  68.     }
  69.   }
  70. }
复制代码

作者: w31575801    时间: 2020-11-27 01:29

回复 32# flashercs


    已采纳,万分感谢




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2