Board logo

标题: [文本处理] 批处理生成一个数组。求帮助批改 [打印本页]

作者: ohoh    时间: 2023-3-27 01:01     标题: 批处理生成一个数组。求帮助批改

目的,根据输入的行数和列数,生成一个csv表格。如3行4列,结果:
1,2,3,4
2,3,4,5
3,4,5,6
希望生成的行100万,列5000。我尝试的代码:
@echo off
echo 输入行数
set /p hall=
echo 输入列数
set /p lall=
set /a hnum=1
set /a tem=0
set hchart=0

:st

if %hnum% leq %hall% ( goto addhang
                      :write
                      echo %lnum% >> 1.csv
                      echo 完成写入第%hnum% 行
                      set /a hnum=%hnum%+1
                      goto st
)

pause
exit

:addhang

echo 开始写入%hnum%整行
set  lnum=%hnum%
set ltemp=1

:addh2

set hchart=%lnum%,
if %ltemp% lss %lall% ( set hchart=%lnum%,
                        set /a lnum=%lnum%+1
                        set /a ltemp=%ltemp%+1
                        set /p =%hchart%<nul >> 1.csv
                        goto addh2
)
goto write

尝试可以正常运行,但是速度相当的慢。也就是效率很低。
第一个问题,如何修改以便提升效率,
第二个问题,set hchart=%lnum%,,为什么一定要放在外面,放在if后就会出现得出这样的结果
1,2,4
3,2,3,5
4,3,4,6

新手拜大神们解惑。
作者: terse    时间: 2023-3-27 08:10

用for循环应该可以提升效率
对于if后变量的赋值,变量延迟了解一下就明白了
作者: Batcher    时间: 2023-3-27 09:11

回复 1# ohoh


推荐阅读:批处理中的变量延迟扩展
http://bbs.bathome.net/thread-2899-1-1.html
作者: czjt1234    时间: 2023-3-27 09:16

echo %lnum% >> 1.csv

每次该命令都会执行一次写硬盘操作,当然慢了
全部或部分写入内存,然后写入硬盘
作者: qixiaobin0715    时间: 2023-3-27 09:36

5000列?恐怕已超出批处理变量的长度限制。可考虑用其它脚本。
作者: czjt1234    时间: 2023-3-27 12:08

  1. ' & cls & cscript /nologo /e:vbs "%~f0" >1.csv & pause & exit
  2. H = 500    '输入行数
  3. L = 60     '输入列数
  4. begin = Timer()
  5. ReDim arr1(L - 1), arr2(H - 1)
  6. For j = 1 To H
  7.     For i = j To j + L - 1
  8.         arr1(i - j) = i
  9.     Next
  10.     arr2(j - 1) = Join(arr1, ",")
  11. Next
  12. s = Join(arr2, vbCrLf)
  13. finish = Timer()
  14. WScript.Echo finish - begin & "秒"
  15. WScript.Echo s
复制代码
自己修改行数
作者: buyiyang    时间: 2023-3-27 12:37

本帖最后由 buyiyang 于 2023-3-27 12:48 编辑

bat
  1. #@&cls&powershell -sta "gc '%~f0'|out-string|iex"&pause&exit
  2. $csvFileName = "1.csv"
  3. $numberOfRows = 1000000
  4. $numberOfColumns = 5000
  5. $csharpCode = @"
  6. using System.IO;
  7. using System.Text;
  8. public static class GenerateCSV {
  9.     public static void GenerateCSVFile(string fileName, int numberOfRows, int numberOfColumns) {
  10.         using (var streamWriter = new StreamWriter(fileName, false, Encoding.UTF8)) {
  11.             for (int row = 1; row <= numberOfRows; row++) {
  12.                 StringBuilder lineBuilder = new StringBuilder();
  13.                 for (int col = row; col < row + numberOfColumns; col++) {
  14.                     if (col > row) {
  15.                         lineBuilder.Append(",");
  16.                     }
  17.                     lineBuilder.Append(col.ToString());
  18.                 }
  19.                 streamWriter.WriteLine(lineBuilder.ToString());
  20.             }
  21.         }
  22.     }
  23. }
  24. "@
  25. Add-Type -TypeDefinition $csharpCode -Language CSharp
  26. [GenerateCSV]::GenerateCSVFile($csvFileName, $numberOfRows, $numberOfColumns)
  27. Write-Host "$csvFileName OK"
复制代码

作者: ohoh    时间: 2023-3-27 21:19

回复 3# Batcher


    自细学习了,虽然还是不太明白,不过知道了使用  setloacl ENABLEDELAYEDEXPANSION 这个命令来启用"延迟环境变量扩展",变量格式用!name!替换%name%,就可以在嵌套里正常给变量赋值了。
作者: ohoh    时间: 2023-3-27 21:26

回复 7# buyiyang


    感谢,使用你的方法,已解决问题。
作者: hlzj88    时间: 2023-3-28 00:49

本帖最后由 hlzj88 于 2023-3-28 00:57 编辑
  1. @echo off&setlocal enabledelayedexpansion
  2. del /q 3*.*>nul 2>nul
  3. set /p hs=---行数---》
  4. set /p ls=---列数---》
  5. for /l %%i in (1,1,%hs%) do (
  6.   set /a js=%%i+%ls%-1
  7.   for /l %%j in (%%i,1,!js!) do (
  8.      echo %%j,
  9.      )>>33.html
  10.     echo ^<br^>>>33.html
  11. echo %%i|findstr /e "00"&&htox32c /IP /S1 /O0 33.html&&type 33.txt>>结果.txt&&del /q 3*.*>nul
  12.   )
  13. if exist 33.html htox32c /IP /S1 /O0 33.html&&type 33.txt>>结果.txt&&del /q 3*.*>nul
  14. pause
复制代码
贴这个,不代表速度,只说明一个方法。
多次使用hto32c,是怕文件太大,不可以处理。
作者: terse    时间: 2023-3-28 13:58

回复 10# hlzj88
这个纯P方法 还不如两个FOR来得直接;用FINDSTR就已经很吃力了 还要第三方再处理
作者: hlzj88    时间: 2023-3-28 14:31

回复 11# terse


    主要是估计要把5000个数合成一行,用set要循环次数太多,感觉这样会效率高些。倒是没有试过一直set的效率。
作者: 77七    时间: 2023-3-28 14:48

回复 11# terse

大佬,请教一下,两个for是如何实现的呢,我试过5000个数合成一行,超长了,好像只显示到1800左右,越往下越短
作者: qixiaobin0715    时间: 2023-3-28 15:02

回复 13# 77七
用变量的话,字符数有限制,大概是8千多,只能考虑多个变量拼接,太复杂,效率成问题。
作者: terse    时间: 2023-3-28 15:53

回复 13# 77七

ste /p
  1. @echo off&setlocal enabledelayedexpansion
  2. set /a rows=100,cols=5000
  3. (for /l %%i in (1,1,%rows%) do (
  4.      for /l %%j in (%%i,1,!cols!) do set/p=%%j,<nul
  5.      echo;
  6.      set /a cols+=1
  7. ))>2.csv
  8. pause
复制代码

作者: 77七    时间: 2023-3-28 16:07

回复 15# terse


   谢谢大佬指教!学习了!
作者: hlzj88    时间: 2023-3-29 21:23

  1. for /l %%j in (%%i,1,!cols!) do set/p=%%j,<nul
复制代码
这个语句,我一直理解的是 会产生 3  2  1 的效果,而不是 1  2  3的效果,实例证明我理解有问题。




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