[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] powershell快速创建\分割大文本

想用powershell写一个按行数分割文本的脚本。
于是用以下代码生成300000行的txt,耗时80秒!
  1. 1..300000 >30w.txt
复制代码
用以下代码按行数(15000行)来分割30w.txt成20个小文本,耗时0.7秒!
  1. $txt="30w.txt"
  2. $lines=15000
  3. $name=(dir $txt).basename
  4. $ext=(dir $txt).extension
  5. $sn=$begin=0
  6. $filecontent=gc $txt -readcount 0
  7. do{
  8. $lend=$lbegin+$lines-1
  9. $cut=$filecontent[$lbegin..$lend]
  10. $sn++
  11. $fname="{0}{1}{2:d3}{3}" -f $name,"_",$sn,$ext
  12. sc -value $cut $fname
  13. clv cut
  14. $lbegin+=$lines
  15. }until($lbegin -ge $filecontent.length)
  16. write-host "$txt 切分完毕"
  17. write-host "共$sn 个文本"
  18. #$null=[console]::readkey()
复制代码
不能理解,为啥两者用时会相差这么远
另,有更好的方法来生成或者分割这样的大文本吗?谢谢。

本帖最后由 wudi61600963 于 2021-12-15 03:17 编辑

Powershell 是解释型的脚本语言,排除实现方法和优化问题外想了解具体速度差异建议了解背后编译的过程(解释器),解释器在解释不同语法组合时难免会产生额外操作,因此带来了不同的执行效率。
此外,运行效率来说越接近底层越高效。Powershell 可以通过使用 .net 语法来达到近乎最高效。

对于楼主的情况如果每行文本长度固定的话可以考虑通过文件大小来分割,应该能做到更快。
  1. $fromFile=[io.file]::OpenRead('文件路径')
  2. $buff=New-Object byte[] 字节数
  3. $count=$i=0
  4. do{
  5.   $count=$fromFile.Read($buff,0,$buff.Length)
  6.   if($count -gt 0){
  7.     $to='分割文件名{0}' -f ($i)
  8.     $toFile=[io.file]::OpenWrite($to)
  9.     try{
  10.         $tofile.Write($buff,0,$count)
  11.     }finally{
  12.         $tofile.Close()
  13.     }
  14.   }
  15.   $i++
  16. }while($count -gt 0)
  17. $fromFile.Close()
复制代码
最后,降低操作量也是优化效率的关键。例如上述代码中,跳过输出非必要分段也可以进一步提升效率。
1

评分人数

TOP

https://www.pstips.net/speeding-up-powershell-multithreading.html
这里补充一点关于powershell效率的知识

TOP

本帖最后由 WHY 于 2021-12-13 23:43 编辑

> 是重定向,等同于 管道符 + 不带其它参数的 Out-File
即等同于:
  1. 1..300000 | Out-File a.txt
复制代码
管道(重定向)就像阀门,细水长流,速度不快,但资源占用比 for 循环一次性读取要好。
如果速度比资源占用更重要,可以考虑少用甚至不用管道。
1

评分人数

    • for_flr: 原来是重定向的锅技术 + 1

TOP

  1. $arr=1..300000;
  2. $file='30w.txt';
  3. Out-File -literal $file -input $arr -enco default;
  4. Set-Content -literal $file -value $arr -enco default;
  5. [IO.File]::WriteAllLines($file, $arr, [Text.Encoding]::GetEncoding('GB2312'));
复制代码
1

评分人数

提供bat代写,为你省时省力省事,支付宝扫码头像支付
微信: unique2random

TOP

返回列表