Разделить текстовый файл на несколько текстовых файлов с помощью командной строки
У меня есть несколько текстовых файлов, содержащих около 100 000 строк, и я хочу разбить их на более мелкие текстовые файлы по 5000 строк.
Я использовал:
split -l 5000 filename.txt
Это создает файлы:
xaa
xab
aac
xad
xbe
aaf
файлы без расширений. Я просто хочу называть их чем-то вроде:
file01.txt
file02.txt
file03.txt
file04.txt
или если это невозможно, я просто хочу, чтобы у них было расширение ".txt".
Ответы
Ответ 1
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET /a fcount=100
SET /a llimit=5000
SET /a lcount=%llimit%
FOR /f "usebackqdelims=" %%a IN ("%sourcedir%\q25249516.txt") DO (
CALL :select
FOR /f "tokens=1*delims==" %%b IN ('set dfile') DO IF /i "%%b"=="dfile" >>"%%c" ECHO(%%a
)
GOTO :EOF
:select
SET /a lcount+=1
IF %lcount% lss %llimit% GOTO :EOF
SET /a lcount=0
SET /a fcount+=1
SET "dfile=%sourcedir%\file%fcount:~-2%.txt"
GOTO :EOF
Здесь вы можете создать собственную серию окон, которая должна выполнить задачу.
Теперь я не буду говорить, что он будет быстрым (менее 2 минут для каждого выходного файла 5Kline) или что он будет невосприимчив к пакетным символьным сенсибитивам. Действительно зависит от характеристик ваших целевых данных.
Я использовал файл с именем q25249516.txt
, содержащий 100K строк данных для моего тестирования.
Пересмотренная более быстрая версия
REM
@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET /a fcount=199
SET /a llimit=5000
SET /a lcount=%llimit%
FOR /f "usebackqdelims=" %%a IN ("%sourcedir%\q25249516.txt") DO (
CALL :select
>>"%sourcedir%\file$$.txt" ECHO(%%a
)
SET /a lcount=%llimit%
:select
SET /a lcount+=1
IF %lcount% lss %llimit% GOTO :EOF
SET /a lcount=0
SET /a fcount+=1
MOVE /y "%sourcedir%\file$$.txt" "%sourcedir%\file%fcount:~-2%.txt" >NUL 2>nul
GOTO :EOF
Обратите внимание, что я использовал llimit
50000 для тестирования. Перезапишет ранние номера файлов, если llimit
* 100 - редуктор, чем количество строк в файле (вылечите, установив fcount
в 1999
и используйте ~3
вместо ~2
в строке переименования файлов. )
Ответ 2
Я знаю, что вопрос задан давно, но я удивлен, что никто не дал самый простой ответ unix:
split -l 5000 -d --additional-suffix=.txt $FileName file
-
-l 5000
: разделить файл на файлы по 5000 строк каждый.
-
-d
: числовой суффикс. Это заставит суффикс перейти от 00 до 99 по умолчанию вместо aa в zz.
-
--additional-suffix
: позволяет указать суффикс, здесь расширение
-
$FileName
: имя файла, который нужно разделить.
-
file
: префикс для добавления к результирующим файлам.
Как обычно, ознакомьтесь с man split
для более подробной информации.
Ответ 3
Вот пример в С# (это то, что я искал). Мне нужно было разделить 23 ГБ csv файл с примерно 175 миллионами строк, чтобы иметь возможность просматривать файлы. Я разделил его на файлы по миллиону строк. Этот код сделал это примерно через 5 минут на моей машине:
var list = new List<string>();
var fileSuffix = 0;
using (var file = File.OpenRead(@"D:\Temp\file.csv"))
using (var reader = new StreamReader(file))
{
while (!reader.EndOfStream)
{
list.Add(reader.ReadLine());
if (list.Count >= 1000000)
{
File.WriteAllLines(@"D:\Temp\split" + (++fileSuffix) + ".csv", list);
list = new List<string>();
}
}
}
File.WriteAllLines(@"D:\Temp\split" + (++fileSuffix) + ".csv", list);
Ответ 4
Синтаксис выглядит так:
$ split [OPTION] [INPUT [PREFIX]]
где префикс
PREFIXaa, PREFIXab,...
Просто используйте правильный, и вы сделали или просто используете mv для переименования.
я думаю
$ mv * *.txt
должен работать, но сначала проверять его на меньших масштабах.
:)
Ответ 5
Возможно, вы можете сделать что-то подобное с помощью awk
awk '{outfile=sprintf("file%02d.txt",NR/5000+1);print > outfile}' yourfile
В основном, он вычисляет имя выходного файла, беря номер записи (NR) и деля его на 5000, добавляя 1, беря целое число этого и нулевое дополнение к 2 местам.
По умолчанию awk
печатает всю входную запись, если вы ничего не укажете. Таким образом, print > outfile
записывает всю входную запись в выходной файл.
Поскольку вы работаете в Windows, вы не можете использовать одинарные кавычки, потому что это не нравится. Я думаю, вы должны поместить script в файл, а затем сообщить awk
, чтобы использовать файл, примерно так:
awk -f script.awk yourfile
и script.awk
будет содержать script следующим образом:
{outfile=sprintf("file%02d.txt",NR/5000+1);print > outfile}
Или это может сработать, если вы это сделаете:
awk "{outfile=sprintf(\"file%02d.txt\",NR/5000+1);print > outfile}" yourfile
Ответ 6
Мои требования были немного разными. Я часто работаю с файлами с разделителями-запятыми и с разделителями табуляции ASCII, где одна строка является одной записью данных. И они действительно большие, поэтому мне нужно разбить их на управляемые части (сохраняя строку заголовка).
Итак, я вернулся к своему классическому методу VBScript и объединил небольшой .vbs script, который можно запустить на любом компьютере Windows (он автоматически запускается движком WScript.exe script в окне).
Преимущество этого метода заключается в том, что он использует текстовые потоки, поэтому базовые данные не загружаются в память (или, по крайней мере, не все одновременно). В результате это происходит исключительно быстро и на самом деле не нужно много памяти для запуска. Тестовый файл, который я только что разделил, используя этот script на моем i7, составлял около 1 ГБ в размере файла, имел около 12 миллионов строк теста и составлял 25 файлов частей (каждая из которых имела около 500 тыс. Строк каждая) - обработка заняла около 2 минут и он не переходил на 3 МБ памяти, используемой в любой точке.
Оговорка здесь заключается в том, что он полагается на текстовый файл с "строками" (что означает, что каждая запись разделена CRLF), поскольку объект Text Stream использует функцию "ReadLine" для обработки одной строки за раз. Но эй, если вы работаете с TSV или CSV файлами, это идеально.
Option Explicit
Private Const INPUT_TEXT_FILE = "c:\bigtextfile.txt" 'The full path to the big file
Private Const REPEAT_HEADER_ROW = True 'Set to True to duplicate the header row in each part file
Private Const LINES_PER_PART = 500000 'The number of lines per part file
Dim oFileSystem, oInputFile, oOutputFile, iOutputFile, iLineCounter, sHeaderLine, sLine, sFileExt, sStart
sStart = Now()
sFileExt = Right(INPUT_TEXT_FILE,Len(INPUT_TEXT_FILE)-InstrRev(INPUT_TEXT_FILE,".")+1)
iLineCounter = 0
iOutputFile = 1
Set oFileSystem = CreateObject("Scripting.FileSystemObject")
Set oInputFile = oFileSystem.OpenTextFile(INPUT_TEXT_FILE, 1, False)
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)
If REPEAT_HEADER_ROW Then
iLineCounter = 1
sHeaderLine = oInputFile.ReadLine()
Call oOutputFile.WriteLine(sHeaderLine)
End If
Do While Not oInputFile.AtEndOfStream
sLine = oInputFile.ReadLine()
Call oOutputFile.WriteLine(sLine)
iLineCounter = iLineCounter + 1
If iLineCounter Mod LINES_PER_PART = 0 Then
iOutputFile = iOutputFile + 1
Call oOutputFile.Close()
Set oOutputFile = oFileSystem.OpenTextFile(Replace(INPUT_TEXT_FILE, sFileExt, "_" & iOutputFile & sFileExt), 2, True)
If REPEAT_HEADER_ROW Then
Call oOutputFile.WriteLine(sHeaderLine)
End If
End If
Loop
Call oInputFile.Close()
Call oOutputFile.Close()
Set oFileSystem = Nothing
Call MsgBox("Done" & vbCrLf & "Lines Processed:" & iLineCounter & vbCrLf & "Part Files: " & iOutputFile & vbCrLf & "Start Time: " & sStart & vbCrLf & "Finish Time: " & Now())
Ответ 7
Эта программа командной строки Windows "Файл Splitter" работает красиво: https://github.com/dubasdey/File-Splitter
Он с открытым исходным кодом, прост, документирован, проверен и работает для меня.
Пример:
fsplit -split 50 mb mylargefile.txt
Ответ 8
вот один из С#, который не исчерпывает память при разбиении на большие куски! Мне нужно было разделить 95M файл на 10M-строки.
var fileSuffix = 0;
int lines = 0;
Stream fstream = File.OpenWrite($"{filename}.{(++fileSuffix)}");
StreamWriter sw = new StreamWriter(fstream);
using (var file = File.OpenRead(filename))
using (var reader = new StreamReader(file))
{
while (!reader.EndOfStream)
{
sw.WriteLine(reader.ReadLine());
lines++;
if (lines >= 10000000)
{
sw.Close();
fstream.Close();
lines = 0;
fstream = File.OpenWrite($"{filename}.{(++fileSuffix)}");
sw = new StreamWriter(fstream);
}
}
}
sw.Close();
fstream.Close();
Ответ 9
Я создал простую программу для этого, и ваш вопрос помог мне завершить решение...
Я добавил еще одну функцию и несколько конфигураций.
Если вы хотите добавить конкретный символ/строку после каждых нескольких строк (настраиваемый). Пожалуйста, просмотрите заметки.
Я добавил файлы кода:
https://github.com/mohitsharma779/FileSplit