Як розділити stdout, щоб перейти до декількох вихідних файлів?


12

Скажімо, у мене є команда, commandяка друкує величезну кількість рядків до stdout:

line1
line2
.....
lineN

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

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-, виводить купу файлів 100MB з іменем somedir.tar.part-000, 001, 002 ans тощо.
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 Дякую Тільки моя printfне має -vкомутатора. ( bash 4.2.10). Принаймні, це не в manpage відprintf
xralf

1
man printfдокументи / usr / bin / printf, які ніколи в житті не могли встановити змінну середовища. Дивіться документацію help printfщодо printfвбудованої оболонки.
манатура

@manatwork Гаразд. Здається, в ++/частині ще є синтаксична помилка .
xralf

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