Окончательная версия, клянусь ... :)
Предполагается, что:
Эта версия гарантирует, что файлы меньшего размера будут содержать количество строк, меньшее или равное указанному верхнему пределу (т. е. СТРОКИ ).
#!/usr/bin/awk -f
BEGIN {
numberOfLinesInCurrentFile=0;
numberOfLinesInBuffer=0;
filenumber=0;
header="";
previousITEM="";
FS=",";
timestamp=ENVIRON["TIMESTAMP"];
numberOfLinesPerFile=ENVIRON["LINES"];
currentFilename=FILENAME "-" timestamp "-00";
}
{
if (NR == 1) {
header=$0;
print header >> currentFilename;
numberOfLinesInCurrentFile=1;
} else {
currentITEM=$1;
if (previousITEM != currentITEM) {
for (i=0; i<numberOfLinesInBuffer; i++) {
print bufferOfLines[i] >> currentFilename;
}
numberOfLinesInCurrentFile+=numberOfLinesInBuffer;
numberOfLinesInBuffer=0;
bufferOfLines[1]=$0
}
if ((numberOfLinesInCurrentFile+numberOfLinesInBuffer) >= numberOfLinesPerFile) {
filenumber++;
currentFilename=sprintf("%s-%s-%02d", FILENAME, timestamp, filenumber);
print header >> currentFilename;
numberOfLinesInCurrentFile=1;
}
bufferOfLines[numberOfLinesInBuffer++]=$0
previousITEM=$1;
}
}
LINES используется для указания максимального количества строк на файлы меньшего размера.
TIMESTAMP используется для указания метки времени.
bigfile - это файл для разделения.
Тест приведен ниже:
LINES=4000 TIMESTAMP=20160320101538 ./scriptv2.awk bigfile
ls bigfile*
bigfile bigfile-20160320101538-02 bigfile-20160320101538-04 bigfile-20160320101538-06 bigfile-20160320101538-08
bigfile-20160320101538-01 bigfile-20160320101538-03 bigfile-20160320101538-05 bigfile-20160320101538-07
ВТОРАЯ ВЕРСИЯ ДЛЯ СПРАВКИ: он не гарантирует, что количество строк в каждом меньшем файле будет ниже указанного предела.
Быстро протестировали еще одну версию. Предполагается, что первая строка содержит заголовок, а ITEM всегда является первым столбцом. Все строки с одинаковым номером ПУНКТА идут подряд.
cat script.awk
#!/usr/bin/awk -f
BEGIN {
filenumber=0;
header="";
previousITEM="";
FS=",";
timestamp=ENVIRON["TIMESTAMP"];
numberOfLinesPerFile=ENVIRON["LINES"];
currentFilename=FILENAME "-" timestamp "-00";
changeFilenameWhenPossible=0;
}
{
if (NR == 1) {
header=$0;
} else {
currentITEM=$1;
if (NR % numberOfLinesPerFile == 0) {
if (previousITEM != currentITEM) {
filenumber=filenumber+1;
filenamberString=sprintf("%02d",filenumber);
currentFilename=FILENAME "-" timestamp "-" filenamberString;
changeFilenameWhenPossible=0;
print header >> currentFilename;
} else {
changeFilenameWhenPossible=1;
}
} else if (changeFilenameWhenPossible == 1 && previousITEM != currentITEM) {
filenumber=filenumber+1;
filenamberString=sprintf("%02d",filenumber);
currentFilename=FILENAME "-" timestamp "-" filenamberString;
changeFilenameWhenPossible=0;
print header >> currentFilename;
}
previousITEM=$1;
}
print $0 >> currentFilename;
}
LINES должен быть установлен на количество строк, необходимых для файлов меньшего размера.
TIMESTAMP должен быть установлен на указанную метку времени.
bigfile - файл размером 2M строк.
Тест приведен ниже:
chmod +x script.awk
LINES=200000 TIMESTAMP=20160318101538 ./script.awk bigfile
ls -1 bigfile-*
bigfile-20160318101538-01
bigfile-20160318101538-02
bigfile-20160318101538-03
bigfile-20160318101538-04
bigfile-20160318101538-05
bigfile-20160318101538-06
bigfile-20160318101538-07
bigfile-20160318101538-08
bigfile-20160318101538-09
bigfile-20160318101538-10
Для справки, первый ответ ...
Я заметил, что вы хотели бы избавиться от самой первой строки с заголовком, верно?
#!/bin/bash --
nblines=$(wc -l "${1}" | cut -d\ -f1)
nblines=$(((nblines - 1)/10))
tail -n +2 "${1}" | split -l $nblines -d -- - "${1}"-"${2}"-
touch -r "${1}" ./"${1}"?*
Обязательно проверьте с помощью большой файл , содержащий 11 или более строк.
Команда touch используется для применения времени большого файла ко всем только что созданным меньшим файлам. Удалите , прикоснитесь к , если он не нужен.
новая правка еще не проверена:
ls
bigfile
script.sh
chmod +x ./script.sh
./script.sh bigfile 20160309144430
ls -l bigfile*
-rw-r--r-- 1 jay stackgrp 556 Mar 16 17:03 bigfile
-rw-r--r-- 1 jay stackgrp 92 Mar 16 17:03 bigfile-20160309144430-00
-rw-r--r-- 1 jay stackgrp 42 Mar 16 17:03 bigfile-20160309144430-01
и т. Д.
Обратите внимание, что ls показывает одно и то же время для всех файлов bigfile * благодаря команде touch .