Автор Гілка: sed і розбиття тексту на рядки…  (Прочитано 1323 раз)

Відсутній tivasyk

  • Кореспондент
  • ***
  • дописів: 156
  • Карма: +0/-0
панове, поможіть приборкати sed. задачка проста — розбити текст на рядки довжиною, скажімо, не більше 40 символів, з переносами на пробілах (fold чи fmt якось некоректно працюють з кириличним текстом). прийшов до такого:

sed -e :a -e 's/^\(.\{1,40\} \)/\1\n/;P;D;ta'
і в принципі, все працює як треба… за винятком одного маленького нюансу: останній фрагмент потрібної довжини завжди розбивається ще раз так, щоб останній рядок виводу містить одне «слово» (фрагмент після останнього пробілу).

що я роблю не так?
« Змінено: 2010-10-05 10:52:16 від tivasyk »
«it’s quite easy if you don’t know how» (c) douglas adams

Відсутній nickat

  • Письменник
  • *****
  • дописів: 587
  • Карма: +0/-0
  • Debian user
Re: sed і розбиття тексту на рядки…
« Відповідей #1 : 2010-10-04 23:09:55 »
Якщо спочатку видалити всі newline, то все працює:

$ cat a.txt | tr '\n' ' ' | sed -e :a -e 's/^\(.\{1,40\} \)/\1\n/;P;D;ta'
фва фіва фіва ф іва фіва фі ва фіва фіва
фі а фіва фіа фіва фіва фі ва фіав фіва  
йцук йцук й цук йцук йцук йц укй цук
йцук йцу кйц укй цук йцук йцук йц укй
цук щзшгзшщг зщшг

sed та видалення newline — це окрема розмова.  Можна так:
sed ':a;N;$!ba;s/\n/ /g'
Але, як це вставити у ваш код, не підкажу.
Best regards,
nickat

Відсутній tivasyk

  • Кореспондент
  • ***
  • дописів: 156
  • Карма: +0/-0
Re: sed і розбиття тексту на рядки…
« Відповідей #2 : 2010-10-05 09:41:17 »
Якщо спочатку видалити всі newline, то все працює

так, проте працює не так, як треба — в цім випадку tr поєднує увесь текст в один рядок, а це не зовсім (зовсім не) те, що потрібно, бо на вході маю кілька довгих рядків, кожен з котрих тре розбить на короткі — але зберігши оригінальні lf…

…я бачу, що не до кінця розумію логіку мною ж запропонованої команди для sed’а, може хто розтлумачить докладно, що саме я впустив з виду?

p.s. ага, починаю розуміти — проблема в тім пробілі після \} у regexp’і, котрий не дозволяє sed’ові взяти увесь останній рядок, змушуючи розбивати його на частини аж допоки в остатку не буде жодного пробілу =( теоретично треба змусити його розбивати рядок або на пробілі — або на кінцевому $, але як? $ в або-групі [] інтерпретується дослівно, а не позначає кінець рядка…

p.p.s. тимчасове рішення: перед поділом на рядки додати до поточного рядка кінцевий пробіл…

sed -e 's/$/ /' -e :a -e 's/^\(.\{1,40\} \)/\1\n/;P;D;ta'
побічний ефект — у виводі текст ділиться на «абзаци» зайвим lf — мене влаштовує. але це не елегантно =(
« Змінено: 2010-10-05 10:52:04 від tivasyk »
«it’s quite easy if you don’t know how» (c) douglas adams