【问题标题】:How to split large text file in windows?如何在windows中拆分大文本文件?
【发布时间】:2015-10-25 12:01:12
【问题描述】:

我有一个大小为 2.5 GB 的日志文件。有没有办法使用 windows 命令提示符将此文件拆分为较小的文件?

【问题讨论】:

标签: windows text cmd split size


【解决方案1】:

以下代码每 500 个文件拆分一次

@echo off
setlocal ENABLEDELAYEDEXPANSION
REM Edit this value to change the name of the file that needs splitting. Include the extension.
SET BFN=upload.txt
REM Edit this value to change the number of lines per file.
SET LPF=15000
REM Edit this value to change the name of each short file. It will be followed by a number indicating where it is in the list.
SET SFN=SplitFile

REM Do not change beyond this line.

SET SFX=%BFN:~-3%

SET /A LineNum=0
SET /A FileNum=1

For /F "delims==" %%l in (%BFN%) Do (
SET /A LineNum+=1

echo %%l >> %SFN%!FileNum!.%SFX%

if !LineNum! EQU !LPF! (
SET /A LineNum=0
SET /A FileNum+=1
)

)
endlocal
Pause

见下文: https://forums.techguy.org/threads/solved-split-a-100000-line-csv-into-5000-line-csv-files-with-dos-batch.1023949/

【讨论】:

    【解决方案2】:

    当然有! Win CMD 可以做的不仅仅是分割文本文件:)

    将一个文本文件拆分成单独的文件,每个文件包含 'max' 行:

    Split text file (max lines each):
    : Initialize
    set input=file.txt
    set max=10000
    
    set /a line=1 >nul
    set /a file=1 >nul
    set out=!file!_%input%
    set /a max+=1 >nul
    
    echo Number of lines in %input%:
    find /c /v "" < %input%
    
    : Split file
    for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
    
    if !line!==%max% (
    set /a line=1 >nul
    set /a file+=1 >nul
    set out=!file!_%input%
    echo Writing file: !out!
    )
    
    REM Write next file
    set a=%i
    set a=!a:*]=]!
    echo:!a:~1!>>out!
    set /a line+=1 >nul
    )
    

    如果上述代码挂起或崩溃,此示例代码会更快地拆分文件(通过将数据写入中间文件而不是将所有内容保存在内存中):

    例如。将包含 7,600 行的文件拆分为最多 3000 行的较小文件。

    1. 使用set 命令生成正则表达式字符串/模式文件,以提供给findstr/g 标志

    list1.txt

    \[[0-9]\]
    \[[0-9][0-9]\]
    \[[0-9][0-9][0-9]\]
    \[[0-2][0-9][0-9][0-9]\]

    list2.txt

    \[[3-5][0-9][0-9][0-9]\]

    list3.txt

    \[[6-9][0-9][0-9][0-9]\]

    1. 将文件拆分为更小的文件:
    type "%input%" | find /v /n "" | findstr /b /r /g:list1.txt > file1.txt
    type "%input%" | find /v /n "" | findstr /b /r /g:list2.txt > file2.txt
    type "%input%" | find /v /n "" | findstr /b /r /g:list3.txt > file3.txt
    
    1. 删除前缀行号为每个文件拆分:
      例如。第一个文件:
    for /f "tokens=* delims=[" %i in ('type "%cd%\file1.txt"') do (
    set a=%i
    set a=!a:*]=]!
    echo:!a:~1!>>file_1.txt)
    

    注意事项:
    适用于前导空格、空白行和空白行。

    在 Win 10 x64 CMD 上测试,4.4GB 文本文件,5651982 行。

    【讨论】:

      【解决方案3】:

      如果你安装了Git for Windows,你应该安装 Git Bash,因为 Git 自带。

      在 Git Bash 中使用 split 命令拆分文件:

      • 到每个大小为 500MB 的文件中:split myLargeFile.txt -b 500m

      • 到每个 10000 行的文件中:split myLargeFile.txt -l 10000

      提示:

      • 如果您没有 Git/Git Bash,请在 https://git-scm.com/download 下载

      • 如果您丢失了 Git Bash 的快捷方式,您可以使用 C:\Program Files\Git\git-bash.exe

        运行它

      就是这样!


      虽然我总是喜欢例子......

      示例:

      您可以在这张图片中看到split生成的文件被命名为xaaxabxac等。

      这些名称由您可以指定的前缀和后缀组成。由于我没有指定前缀或后缀的外观,因此前缀默认为x,后缀默认为两个字符的字母枚举。

      另一个例子:

      这个例子演示

      • 使用文件名前缀MySlice(而不是默认的x),
      • -d 标志用于使用数字后缀(而不是 aaabac 等...),
      • 和选项-a 5 告诉它我希望后缀长度为 5 位:

      【讨论】:

      • 很好的解决方案,有很好的例子。在 Windows 10 中运行良好。对我来说,我使用 split myLogs.log mylogs_ -b 800m -a 3 -d 拆分 4.5Gb 日志文件。
      • 在 Windows 上使用 Git-bash 的不错的解决方案。对于 split 部分,使用 filename prefix-d 选项应该是您的主要答案。相关:stackoverflow.com/a/45761990/1519522
      • 谢谢你,工作得很好!!使用 Windows 10 并且刚接触 Git bash 这可能会有所帮助......默认工作目录是 C:\Users\username(使用“dir”查找当前工作目录)。更改目录的命令是“cd /c/folder”。
      • 好的,但是如果我想在 Git Bash 中选择 *.txt,为什么不起作用?如:split *.txt MyNewText -b 5m
      • 不错!您还可以在输出上设置扩展名......例如--additional-suffix=.txt
      【解决方案4】:

      您可以使用命令 split 执行此任务。 例如这个命令输入到命令提示符中

      split YourLogFile.txt -b 500m
      

      创建多个文件,每个文件大小为 500 MB。对于您大小的文件,这将需要几分钟时间。您可以将输出文件(默认称为“xaa”、“xab”...等)重命名为 *.txt 以在您选择的编辑器中打开它。

      请务必检查命令的帮助文件。您还可以按行数拆分日志文件或更改输出文件的名称。

      (在 Windows 7 64 位上测试)

      【讨论】:

      • "'split' 未被识别为内部或外部命令、可运行程序或批处理文件。" - 在 Win 7 Ultimate SP1,64 位
      • 相信你确实用过gitbash的split
      • 好的,但是如果我想在 Git Bash 中选择 *.txt,为什么不起作用?如:split *.txt MyNewText -b 5m
      【解决方案5】:
      Set Arg = WScript.Arguments
      set WshShell = createObject("Wscript.Shell")
      Set Inp = WScript.Stdin
      Set Outp = Wscript.Stdout
          Set rs = CreateObject("ADODB.Recordset")
          With rs
              .Fields.Append "LineNumber", 4 
      
              .Fields.Append "Txt", 201, 5000 
              .Open
              LineCount = 0
              Do Until Inp.AtEndOfStream
                  LineCount = LineCount + 1
                  .AddNew
                  .Fields("LineNumber").value = LineCount
                  .Fields("Txt").value = Inp.readline
                  .UpDate
              Loop
      
              .Sort = "LineNumber ASC"
      
              If LCase(Arg(1)) = "t" then
                  If LCase(Arg(2)) = "i" then
                      .filter = "LineNumber < " & LCase(Arg(3)) + 1
                  ElseIf LCase(Arg(2)) = "x" then
                      .filter = "LineNumber > " & LCase(Arg(3))
                  End If
              ElseIf LCase(Arg(1)) = "b" then
                  If LCase(Arg(2)) = "i" then
                      .filter = "LineNumber > " & LineCount - LCase(Arg(3))
                  ElseIf LCase(Arg(2)) = "x" then
                      .filter = "LineNumber < " & LineCount - LCase(Arg(3)) + 1
                  End If
              End If
      
              Do While not .EOF
                  Outp.writeline .Fields("Txt").Value
      
                  .MoveNext
              Loop
          End With
      

      剪切

      filter cut {t|b} {i|x} NumOfLines
      

      从文件的顶部或底部减少行数。

      t - top of the file
      b - bottom of the file
      i - include n lines
      x - exclude n lines
      

      示例

      cscript /nologo filter.vbs cut t i 5 < "%systemroot%\win.ini"
      

      另一种方式 这输出行 5001+,适应您的使用。这几乎不占用内存。

      Do Until Inp.AtEndOfStream
               Count = Count + 1
               If count > 5000 then
                  OutP.WriteLine Inp.Readline
               End If
      Loop
      

      【讨论】:

      • 当我尝试运行脚本时出现 filter.vbs(16, 13) Microsoft Cursor Engine: Out of memory 之类的错误。
      • 你有 32 位还是 64 位的窗口。如果 64 位从 64 位版本运行它(c:\windows\sysnative\cscript etc - sysnative 强制运行 System32 文件而不是 SysWoW64 文件用于 32 位进程)。如果是 32 位,我们需要另一种技术,这将是特定的而不是通用的。
      • 我有一个 64 位的窗口。
      • 所以我告诉你在这种情况下该怎么做。 Sysnative 强制 64 位。