Как разделить стандартный вывод, чтобы перейти к нескольким выходным файлам?


12

Скажем, у меня есть команда, commandкоторая выводит огромное количество строк в стандартный вывод:

line1
line2
.....
lineN

Я хочу сохранить вывод на диск, но не как отдельный файл, а как последовательность файлов, каждый из которых имеет 1000 строк стандартного вывода:

file0001.txt:
-------------
line1
....
line1000

file0002.txt:
-------------
line1001
....
line2000

etc

Я пытался найти ответ в Google, но каждый раз, когда Google указывает мне на teeкоманду, что бесполезно в этой ситуации. Возможно, я ввожу неправильные запросы.

Ответы:


24

После того, как вы закончили сохранение файла, вы всегда можете splitфайл на кусочки файла или несколько файлов в зависимости от количества строк.

split -l 1000 output_file

или даже лучше просто попробуйте

command | split -l 1000 -

Это разделит выходной поток на файлы с каждой 1000 строк (по умолчанию 1000 строк без опции -l).

Приведенная ниже команда предоставит вам дополнительную гибкость для установки или применения префикса к имени файла, который будет сгенерирован, когда выходные данные будут сгенерированы и разделены для сохранения в файле.

command | split -l 1000 - small-


Я запутался, поэтому, для других, его split [arguments...] [input e.g. "-" for stdin] [output_prefix], например: tar -c somedir | split --byes 100MB --numeric-suffixes --suffix-length=3 - somedir.tar.part-вывести кучу файлов по 100 МБ с именами somedir.tar.part-000001, 002 и так далее.
ThorSummoner

3

Вы можете использовать скрипт bash lines.bash

#!/bin/bash
a=0
while IFS='' read -r line
do
  printf -v filename "%04d.txt" "$((a++/1000))"
  echo "$line" >> $filename
done

и использовать его как:

cat long_file.txt | bash lines.bash

Единственная проблема, которую я заметил, - *вход в систему long_file.txt(кто-то может исправить это).


2
Установите IFSпустую строку, чтобы избежать разделения слов на read. Используйте, -rчтобы отключить обратную косую черту read. Удалить, -eчтобы избежать обратной косой черты echo. Используйте цитирование, чтобы избежать разделения слов на echo. Используйте -vв bashначиная с версии 4.0 , чтобы избежать запуска суб-процесс. Используйте постинкремент, поскольку ваш текущий код поместит в первый файл только 999 строк. a=0; while IFS='' read -r line; do printf -v filename "%04d.txt" $((a++/1000)); echo "$line" >> "$filename"; done
manatwork

@manatwork Спасибо. Только у меня printfнет -vпереключателя. ( bash 4.2.10). По крайней мере, это не в printf
manpage

1
man printfDocuments / usr / bin / printf, который никогда не сможет установить переменную окружения. Смотрите help printfдля printfвстроенной документации оболочки.
manatwork

@ manatwork ОК. Кажется, в этой ++/части еще есть синтаксическая ошибка .
xralf

1
Еще одна вещь: нет необходимости использовать сигил внутри арифметической оценки, если вам не нужно явное расширение параметров. В арифметическом расширении все равно оцениваются переменные.
manatwork
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.