Board logo

标题: [问题求助] powershell快速创建\分割大文本 [打印本页]

作者: for_flr    时间: 2021-12-13 13:58     标题: 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()
复制代码
不能理解,为啥两者用时会相差这么远
另,有更好的方法来生成或者分割这样的大文本吗?谢谢。
作者: zaqmlp    时间: 2021-12-13 14:39

  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'));
复制代码

作者: WHY    时间: 2021-12-13 23:39

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

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

https://www.pstips.net/speeding-up-powershell-multithreading.html
这里补充一点关于powershell效率的知识
作者: wudi61600963    时间: 2021-12-14 19:01

本帖最后由 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()
复制代码
最后,降低操作量也是优化效率的关键。例如上述代码中,跳过输出非必要分段也可以进一步提升效率。




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