split
Разрезать файл на части по строкам, байтам или числу кусков и собрать обратно
split режет файл (или stdin) на куски: по N строк, по N байт или на N частей. Куски получают имена префикс + суффикс: по умолчанию xaa, xab, xac… Собирают обратно обычным cat, потому что суффиксы идут в алфавитном порядке. В песочнице — GNU coreutils 9.4.
Синтаксис
split [опции] [файл [префикс]]
команда | split [опции] - [префикс]
Без файла или с - читается stdin. Префикс по умолчанию — x. Без опций — куски по 1000 строк.
Опции
Как резать
| Опция | Что делает |
|---|---|
-l N | по N строк в куске |
-b РАЗМЕР | по РАЗМЕР байт (100K, 10M, 1G; KB, MB — степени 1000). Строки рвутся посередине |
-C РАЗМЕР | не больше РАЗМЕР байт, по возможности не разрывая строки; строку длиннее РАЗМЕР всё же разрежет |
-n N | ровно N кусков равного размера в байтах (строки рвутся) |
-n l/N | N кусков, не разрывая строки |
-n r/N | раздать строки по кругу: 1-я — в первый кусок, 2-я — во второй… |
-n K/N | не создавать файлы, а вывести в stdout только K-й кусок из N (также l/K/N, r/K/N) |
-t символ | разделитель записей вместо перевода строки (-t ',', -t '\0') |
-e | с -n не создавать пустые куски |
Имена кусков
| Опция | Что делает |
|---|---|
-a N | длина суффикса (по умолчанию 2: aa…zz — 676 кусков) |
-d | цифровые суффиксы с нуля: 00, 01… |
--numeric-suffixes=1 | цифровые, начиная с заданного числа |
-x | шестнадцатеричные суффиксы: 00…0f… |
--additional-suffix=.txt | дописать расширение после суффикса: part_00.txt |
--verbose | сообщать о каждом созданном файле: creating file 'v_aa' |
--filter='команда' | не писать файлы, а отдать каждый кусок команде; имя куска — в $FILE |
Примеры
# пример данных
seq 1 10 > numbers.txt
# по 4 строки: xaa (1–4), xab (5–8), xac (9–10)
split -l 4 numbers.txt
# понятные имена: part_00, part_01, part_02
split -l 4 -d numbers.txt part_
# с расширением и трёхзначным номером: chunk_000.csv, chunk_001.csv…
split -l 1000 -d -a 3 --additional-suffix=.csv data.csv chunk_
# двоичный файл на куски по 100 МиБ и обратно
split -b 100M backup.tar.gz backup.tar.gz.part_
cat backup.tar.gz.part_* > restored.tar.gz
cmp backup.tar.gz restored.tar.gz && echo 'совпадает'
# на 4 части, не разрывая строки — например, для параллельной обработки
split -n l/4 access.log log_
# только 2-я из 3 частей — в stdout, без файлов
split -n l/2/3 numbers.txt
# из конвейера
seq 1 30 | split -l 10 - batch_
# сразу сжимать каждый кусок
split -l 100000 --filter='gzip > $FILE.gz' big.log big_
# CSV с заголовком: заголовок в каждый кусок
tail -n +2 data.csv | split -l 1000 -d --filter='{ head -1 data.csv; cat; } > $FILE.csv' - part_
Подводные камни
- Старые куски не удаляются. Если раньше получилось
xaa…xac, а теперь толькоxaa, тоxabиxacостанутся от прошлого запуска, иcat x*соберёт мусор. Удаляй старые куски или пиши в чистый каталог. - Суффиксы кончаются. С явным
-a 1больше 26 кусков не сделать: «output file suffixes exhausted», код1. Если-aне задан, GNU split сам удлиняет имена: послеxyzидутxzaaa,xzaab… (с-d: послеx89—x9000), и сортировка по-прежнему правильная. -bи-n Nрежут строки посередине. Для текста, который потом обрабатывается построчно, бери-l,-Cили-n l/N.--filterпиши в одинарных кавычках, чтобы$FILEподставилsplit, а не оболочка заранее.- Порядок сборки.
cat part_*собирает в алфавитном порядке — верно для суффиксовsplit, но не для своих имён вродеpart_1,part_10,part_2. - Префикс с путём:
split -l 100 big.log /tmp/out/part_— каталог/tmp/outдолжен существовать.