找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 14602|回复: 12

[文本处理] 求助批处理从txt文件中随机抽取N行并输出到新的txt文件

[复制链接]
发表于 2025-3-11 11:09:53 | 显示全部楼层 |阅读模式
例:a.txt中有几万行(无固定行数),想从中随机抽取2000行(也可能是1000行),并输出到新的b.txt中,b.txt中被输出的内容也是分行的。
有没有大神帮忙一下,谢谢了
发表于 2025-3-11 13:27:37 | 显示全部楼层
试了一下shuf最快,10万行随机取1000行小于0.1秒
  1. shuf -n 1000 a.txt
复制代码
乱序排序再取值明显慢很多
  1. sort -R a.txt | head -n 1000
复制代码
powershell的Get-Random也有点慢
  1. gc a.txt | Get-Random -Count 10
复制代码

评分

参与人数 1技术 +1 收起 理由
qzwqzw + 1 还是*nix家文本处理底蕴深厚

查看全部评分

发表于 2025-3-11 15:48:18 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-3-11 15:57 编辑

回复 1# tiger7651

批处产生的随机数最大值限于 32767,powershell可以到达 2147483647,且用后者代码会更简洁... 以下代码存为 test1.bat 与源文件 a.txt 同目录运行,代码中预设抽取行数=2000 可自定义

  1. @echo off &set "lines=2000"
  2. powershell "$a=gc 'a.txt' -ReadCount 1000;get-random $a -count %lines%">"b.txt"
  3. pause&exit/b
复制代码
以上代码有可能产生重复随机数,若要求不能重复,须采用以下代码,存为 test2.bat 与源文件 a.txt 同目录运行,代码中预设抽取行数=2000 可自定义

  1. @echo off &set "lines=2000"
  2. powershell "for($i,$a=0,@();$i -lt %lines%;){$r=Get-Random -Min 1 -Max 99999;if(!($a -contains $r)){$i++;$a+=$r}};$s=(gc 'a.txt' -ReadCount 1000);foreach($i in $a){$s[$i-1]}">"b.txt"
  3. pause&exit/b
复制代码

评分

参与人数 1技术 +1 收起 理由
wanghan519 + 1 感谢指点,这就快多了

查看全部评分

 楼主| 发表于 2025-3-11 15:59:23 | 显示全部楼层
回复 2# wanghan519 谢谢!我试了下第三条,很简洁也管用。
 楼主| 发表于 2025-3-12 08:14:32 | 显示全部楼层
回复 3# aloha20200628
谢谢!两段运行得到的结果不太理想,抽取的是相邻数据,楼上第三段倒是输出正确结果。
发表于 2025-3-12 10:09:21 | 显示全部楼层
全部默认编码 ,不重复 ,包括空行 ,不保持原文出现顺序

  1. @echo off
  2. set "file=a.txt"
  3. set "out=b.txt"
  4. set hang=2000
  5. powershell -c "get-random -Count %hang% -InputObject (gc -literalpath '%file%')" >"%out%"
  6. pause&exit/b
复制代码
全部默认编码 ,不重复 ,包括空行 ,保持原文出现顺序

  1. @echo off
  2. set "file=a.txt"
  3. set "out=b.txt"
  4. set hang=2000
  5. powershell -c "$nice=gc -literalpath '%file%';$sai=$nice.length;$t=new-object int[] $sai;for($i=0;$i -lt $sai;$i++){$t[$i]=$i};$r=get-random -Count %hang% -InputObject $t;[Array]::Sort($r);foreach($i in $r){$nice[$i]}" >"%out%"
  6. pause&exit/b
复制代码
 楼主| 发表于 2025-3-12 15:35:16 | 显示全部楼层
回复 6# Five66

谢谢!
发表于 2025-3-12 15:55:00 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-3-12 15:59 编辑

回复 5# tiger7651

在不处理随机数重复性问题时采用的 powershell 方法,各楼代码用的都是 get-random -count ... 句式,都是用同一只手抛骰子,每次结果一定会有密集或离散之别,就是 '随机' 之理了 ...
但是用 gc 读入大数据文件时,用否 -readCount 1000 参数,其效率差别还是很明显的...
 楼主| 发表于 2025-3-13 08:32:21 | 显示全部楼层
回复 8# aloha20200628
-readCount 1000 这个参数是控制什么的?
 楼主| 发表于 2025-3-13 10:17:44 | 显示全部楼层
回复 8# aloha20200628
大神:能否帮忙写一个每20行随机抽取一行的powershell批处理?这个20是可自定义的,这样可以解决密集与分散的问题了。
发表于 2025-3-13 13:03:54 | 显示全部楼层
回复 10# tiger7651

代码中变量 lines 是行数,v 是用来调整 1 至 lines 之间随机数的生成区间,均可自定义...

  1. @echo off &set/a "lines=20, v=5"
  2. powershell "$a=(gc 'a.txt' -ReadCount 1000);for($n,$l=0,$a.length;$n -lt $l;$n+=%lines%){$r=$n+(get-random -min %v% -max (%lines%-%v%));$a[$r]}">"b.txt"
  3. pause&exit/b
复制代码
 楼主| 发表于 2025-3-13 15:31:42 | 显示全部楼层
回复 11# aloha20200628
谢谢,已经用上了!去掉-ReadCount参数就得到我想要的。查了一下`-ReadCount`用于分段读取,应该只影响读取数据速度。但抽取的值的似乎不广,例如:我有30个文件夹文件的路径组成的txt文件,带`-ReadCount`参数后,抽取的路径对应的文件夹只有几个,不带就`-ReadCount` 抽取的路径基本涵盖所有文件夹。
发表于 2025-3-14 02:40:09 | 显示全部楼层
感谢楼上几位大神的答复,学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 07:29 , Processed in 0.029372 second(s), 13 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表