Board logo

标题: [文本处理] 批处理怎样快速获取大文件倒数行? [打印本页]

作者: 娜美    时间: 2023-8-7 21:08     标题: 批处理怎样快速获取大文件倒数行?

获取倒数行,  想获取最后1000行巨慢    一个200mb文件要半天时间
  1. @echo off
  2. for /f "tokens=1* delims=:" %%i in ('type a.txt^|findstr /n "."') do (set n=%%i)
  3. set /a n=%n%-1000
  4. more +%n% a.txt
  5. pause
复制代码
似乎需要使用倒数运算才能加快 获取最后1000行,  即从倒数开始,  而不是从头开始
使用type 如何才能加快倒数运算获取最后1000行呢 ? 谢谢指正
作者: Five66    时间: 2023-8-7 21:20

只知道用第三方程序sed之类的应该快点
作者: pd1    时间: 2023-8-7 21:44

  1. Measure-Command{$a=[io.file]::ReadAllLines(".\in.txt");$b=($a.Length-1)..($a.Length-1000)|%{$a[$_]};[io.file]::WriteAllLines(".\out.txt",$b)}
复制代码
300M文件2秒多吧
作者: 娜美    时间: 2023-8-7 21:46

回复 2# Five66
哦哦,用type不能快了吗
那如果用sed awk那个写法更快
作者: wanghan519    时间: 2023-8-7 21:48

用tail很快,它好像是seek文件末尾逐字节向前读文件,遇到回车就计数这种,平时无脑用,具体怎么实现真不会。。。
作者: 娜美    时间: 2023-8-7 21:57

回复 3# pd1


    嗯嗯哥哥的确实很快,      似乎顺序存放倒转了, 获取到的1000行不是按原顺序输出,
作者: pd1    时间: 2023-8-7 21:59

回复 6# 娜美


    你是说要从最后一行开始吗?想反过来就把-1 和-1000换一下
作者: Five66    时间: 2023-8-7 22:04

回复 4# 娜美

type应该是从头开始的,不能从末尾开始
没用过akw,不知道谁快
作者: 娜美    时间: 2023-8-7 22:05

回复 7# pd1


    Yeah..哥哥的写法很灵巧哦,  学习了
作者: Batcher    时间: 2023-8-7 22:06

回复 1# 娜美
  1. @echo off
  2. tail.exe -1000 a.txt
  3. pause
复制代码
http://bcn.bathome.net/s/tool/index.html?key=tail
作者: 娜美    时间: 2023-8-7 22:07

回复 8# Five66


    sed也很慢吧    应该没有3楼pd1哥哥的ps快
作者: 77七    时间: 2023-8-7 22:11

  1. @echo off
  2. for /f "delims=" %%a in ('find /c /v "" ^<a.txt') do (
  3. set /a n=%%a-1000
  4. )
  5. (for /f "useback skip=%n% delims=" %%a in ("a.txt") do (
  6. echo %%a
  7. ))>b.txt
  8. pause
复制代码

作者: 娜美    时间: 2023-8-7 22:14

回复 10# Batcher


    这确实很快,,   但处理一些UTF16编码文件出来后会发生编码混乱字符
作者: 娜美    时间: 2023-8-7 22:22

回复 12# 77七


    哥哥的用find比我那个快的多
作者: Five66    时间: 2023-8-7 22:37

回复 11# 娜美

知道总行数应该是sed快
不知道总行数ps快吧
作者: wanghan519    时间: 2023-8-8 03:43

本帖最后由 wanghan519 于 2023-8-13 14:26 编辑

1亿行的a.txt,大概888M,
tail -n 1000 a.txt > b.txt耗时0.13秒
作者: aloha20200628    时间: 2023-8-8 12:03


如果不下载第三方,纯P刀法中的最快组合也许就是如下两行代码,其中 more +n 的参数 n=0 是指文件第1行》
   for /f %%i in ('find /v /c "" ^< "源文件" ') do (set/a "n=%%i-1000")
   more +%n% "源文件">"源文件.new"
哪位知其更快者请赐教。
如果下载GNU系列工具,当属 tail 直接了当,sed/awk 显得拖泥带水了。

作者: qixiaobin0715    时间: 2023-8-8 12:06

以前在其它地方使用more,好像还不如for循环快。
作者: aloha20200628    时间: 2023-8-8 12:17

本帖最后由 aloha20200628 于 2023-8-8 12:27 编辑

1楼代码巨慢的瓶颈应该是其获取总行数的方法,for/f 循环中无须用type...findstr...
作者: 77七    时间: 2023-8-8 13:51

本帖最后由 77七 于 2023-8-8 13:55 编辑
  1. 1千万行文本,234 M
  2. 取倒数100行
  3. 13:46:31.12
  4. 执行 find /v 计算行数
  5. 13:46:36.52
  6. 执行 for + skip
  7. 13:46:37.76
  8. 执行 more
  9. 13:46:48.28
  10. 请按任意键继续. . .
  11. 取倒数10000行
  12. 13:46:59.83
  13. 执行 find /v 计算行数
  14. 13:47:05.19
  15. 执行 for + skip
  16. 13:47:07.21
  17. 执行 more
  18. 13:47:17.80
  19. 请按任意键继续. . .
  20. 取倒数100000行
  21. 13:47:33.00
  22. 执行 find /v 计算行数
  23. 13:47:38.41
  24. 执行 for + skip
  25. 13:47:45.14
  26. 执行 more
复制代码

more 确实比较慢,第三段执行超10分钟,手动结束了。测试了两遍,第二遍,加了暂停休息时间,未在测试第三段的more
作者: aloha20200628    时间: 2023-8-8 14:50

选择more是为防for吞不下较长文本行,现有777实测对比,把用c/c++打造的more“原形毕露”了...
作者: jszw666    时间: 2023-8-19 11:05

这,对于我来说,是新东西,从头学学




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