使用Windows批处理脚本拆分文件

6

我有一个csv文件,需要将它分成n个文件,每个分割文件的大小不能超过100MB。我需要在Windows批处理脚本中实现这个功能。我尝试了下面的方法,但是由于我的未分割文件是几GB,所以花费的时间很长。

@echo off
setlocal enableextensions enabledelayedexpansion
set count=1
set maxbytesize=100000000
set size=1
type NUL > output_1.csv

FOR /F  "tokens=*" %%i in (myfile.csv) do (
FOR /F "usebackq" %%A in ('!filename!_!count!.csv') do (
set size=%%~zA) 
if !size! LSS !maxbytesize! (
echo %%i>>!filename!_!count!.csv) else (
set /a count+=1 
echo %%i>>!filename!_!count!.csv 
))

请让我知道是否有更好的方法来实现这个。由于我的服务器是Windows,所以我不能使用其他脚本语言。

是的,基本上你需要在每次迭代中检查文件是否大于100000000,这可能是为什么这个过程如此耗时的原因。如果您不想使用PowerShell或VB,那么您是否愿意下载任何第三方软件,比如7zip,以便更轻松地完成此操作? - rud3y
主要问题在于 for 命令(您可以通过运行空的 FOR /F "tokens=*" %%i in (myfile.csv) do () 循环来检查它),因此您无需处理它。我建议使用更高级别的编程语言。 - Fr0sT
1个回答

2
假设您的行大致相同,那么这个方法就可以解决问题。 它的优点是只需要两次遍历,一次用于计算行数,另一次用于打印行数。
@rem echo off

@rem usage: batchsplit.bat <file-to-split> <size-limit>
@rem it will generate files named <file-to-split>.part_NNN

setlocal EnableDelayedExpansion

set FILE_TO_SPLIT=%1
set SIZE_LIMIT=%2

for /f %%s in ('dir /b %FILE_TO_SPLIT%') do set SIZE=%%~Zs
for /f %%c in ('type "%FILE_TO_SPLIT%"^|find "" /v /c') do set LINE_COUNT=%%c

set /a AVG_LINE_SIZE=%SIZE%/%LINE_COUNT%
set /a LINES_PER_PART=%SIZE_LIMIT%/%AVG_LINE_SIZE%

set "cmd=findstr /R /N "^^" %FILE_TO_SPLIT%"

for /f "tokens=1,2* delims=:" %%a in ('!cmd!') do @(
    set /a ccc = %%a / %LINES_PER_PART%
    echo %%b >> %FILE_TO_SPLIT%.part_!ccc!
)

将其保存为batchsplit.bat并使用以下方式运行:

batchsplit.bat myfile.csv 100000000

set SIZE=%~Z1 也可以起作用。总之,你的解决方案非常好(特别是确定文件行数的方法),但速度较慢。主要瓶颈在于 for 命令。 - Fr0sT
谢谢@Fr0sT。设定大小的建议很好。我知道“for”语句很慢,但那是必要条件。 - Amnon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接