Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Bash: Justify текст  (Прочитано 2248 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Bash: Justify текст
« Ответ #15 : 12 Октября 2014, 19:42:52 »
Azure, fold не умеет выравнивать/растягивать по ширине.

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #16 : 12 Октября 2014, 19:55:15 »
v2@v2:~$ stty size
27 85
v2@v2:~$
Wars ~.o

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #17 : 12 Октября 2014, 20:09:39 »
ArcFi,
Сначала обрезать с помощью fold, потом отцентровать (или в цикле с помощью printf или sed -e :a -e 's/^.\{1,ширина-2\}$/ & /;ta'
« Последнее редактирование: 12 Октября 2014, 21:37:15 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #18 : 12 Октября 2014, 20:15:40 »
http://ubuntuforums.org/showthread.php?t=2028113

Пользователь решил продолжить мысль 12 Октября 2014, 20:16:54:
https://gist.github.com/deshawnbw/6331167
Wars ~.o

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Bash: Justify текст
« Ответ #19 : 12 Октября 2014, 20:37:03 »
sed -e :a -e 's/^.{1;ширина-2}$/ & /;ta'
Оно переносит по буквам, а не по словам.
И растягивать пробелы не умеет.

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #20 : 12 Октября 2014, 21:36:55 »
ArcFi,
Я Вас не узнаю… ;) fold обрезает, sed-скрипт центруетfold -sw 20 text_file | sed -e :a -e 's/^.\{1,18\}$/ & /;ta'Если fold почему-то не нравится то можно заменить его на sedsed 's/\(.\{1,20\}\)\b \?/\1\n/g' | sed -e :a -e 's/^.\{1,18\}$/ & /;ta'
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Bash: Justify текст
« Ответ #21 : 12 Октября 2014, 22:51:08 »
(Нажмите, чтобы показать/скрыть)

Azure, теперь разницу видите?

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #22 : 13 Октября 2014, 02:40:15 »
ArcFi,
Т.е. Вы имеете ввиду выравнивание по ширине? Что-то вродеWIDTH=60;fold -sw $WIDTH file|awk -v w="$WIDTH" '!/\.$/ && NF>0 {$NF=$NF;do for(i=1;i<NF;i++) if(length<w) $i=sprintf("%s ",$i);else break;while(length<w)}1'
« Последнее редактирование: 14 Октября 2014, 16:44:09 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Nikshimi

  • Автор темы
  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #23 : 13 Октября 2014, 22:12:17 »
ArcFi,
Т.е. Вы имеете ввиду выравнивание по ширине? Что-то вродеfold -sw 60 | awk '!/\.$/{$NF=$NF;do for (i=1;i<NF;i++) if (length < 60) $i=sprintf("%s ",$i);else break;while (length < 60);print} /\.$/{print}'

именно такое выравнивание как у ArcFi и нужно ).

Пользователь решил продолжить мысль 13 Октября 2014, 22:33:01:
$ WIDTH=60 ; cat file | par "${WIDTH}j" | sed "s/^/$(printf %-$(((COLUMNS-WIDTH)/2))s)/"
можешь описать что конкретно делает ${WIDTH}j и  sed "s/^/$(printf %-$(((COLUMNS-WIDTH)/2))s)/ ?
« Последнее редактирование: 13 Октября 2014, 22:33:01 от Nikshimi »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #24 : 14 Октября 2014, 15:09:24 »
Сделал вообще без awk,sed и пр.
Код: (bash) [Выделить]
#!/bin/bash
#USAGE: script_name file_to_process [line_width [screen_width]]
 
file_to_process="$1"
screen_width="${3:-$(tput cols)}"     # если не указано принимаем равным ширине терминала
line_width="${2:-$[$screen_width-4]}" # если не указано принимаем на 4 короче ширины терминала
 
while read -a l                       # считываем порезанные строки по словам
do
  n=$[${#l[@]}-1]                     # определяем индекс последнего слова в строке
  if [ $n -ge 0 ]                     # проверяем наличие хоть 1 слова в строке
  then
    if [ "${l[n]: -1}" != "." ]       # проверяем окончание блока (по наличию точки в конце)
    then
      i=0                             # сбрасываем индекс для 1-го слова в строке
      # проверяем длину строки
      while [ $(echo "${l[@]}" | wc -m) -lt "$line_width" ]
      do
        l[i]="${l[i]} "               # добавляем пробел к очередному слову
        if [ $[++i] -eq $n ]          # если дошли до конца строки
        then
          i=0                         # начинаем сначала
        fi
      done
    fi
  fi
  printf "%*s" $[($screen_width-$line_width)/2]
  printf "%s\n" "${l[*]}"
done < <(fold -sw "$line_width" "$file_to_process")
В начале конечно надо проверку на наличие файлов|элементов… но лень.
« Последнее редактирование: 14 Октября 2014, 21:28:15 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ArcFi

  • Старожил
  • *
  • Сообщений: 15189
    • Просмотр профиля
    • aetera.net
Re: Bash: Justify текст
« Ответ #25 : 14 Октября 2014, 17:17:43 »
Azure, недурно. =)
Ещё можно добавить обрезку пробелов по краям строки.

Оффлайн Nikshimi

  • Автор темы
  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #26 : 14 Октября 2014, 17:24:58 »
да, только не по центру делает, а так всё замечательно )

И все равно метов ArcFi делает это лучше как ни крути. Но все равно спс за помощь )

ArcFi, не мог бы в личку объяснить ?
« Последнее редактирование: 14 Октября 2014, 18:03:01 от Nikshimi »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #27 : 14 Октября 2014, 20:48:00 »
Поправил https://forum.ubuntu.ru/index.php?topic=251184.msg1984691#msg1984691 с выравниванием по экрану.
ArcFi,
Чтоб всунуть несколько пробелов sed использовать ИМХО излишне. Предлагаю$ WIDTH=60 ; cat file | par "${WIDTH}j" | xargs -i printf "%*s%s\n" $[($COLUMNS-$WIDE)/2-1] "" "{}"
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн Nikshimi

  • Автор темы
  • Новичок
  • *
  • Сообщений: 12
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #28 : 14 Октября 2014, 22:00:24 »
$ WIDTH=60 ; cat file | par "${WIDTH}j" | xargs -i printf "%*s%s\n" $[($COLUMNS-$WIDE)/2-1] "" "{}"
Можешь объяснить пожалуйста после cat file | что делает?
можно в личку.
« Последнее редактирование: 14 Октября 2014, 22:29:37 от Nikshimi »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6017
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Re: Bash: Justify текст
« Ответ #29 : 15 Октября 2014, 00:42:25 »
Вот вообще без сторонних утилит типа fold, wc и т.д.
Код: (bash) [Выделить]
#!/bin/bash
#USAGE: cat file_to_process | script_name [line_width]

screen_width=$(tput cols)
line_width=${1:-$[$screen_width-4]}
t=$[($screen_width-$line_width)/2]       # рассчитываем сдвиг

function my_print() {
printf "%*s" $t                          # сдвигаем на ½ свободного места
echo "${l[*]}"                           # выводим форматированную строку
}

while read -a line                       # считываем строку в виде массива слов
do
  if [ "${line[*]}" ]                    # проверяем пустая строка или нет
  then
    n=0                                  # сбрасываем длину подстроки
    for ((i=0;i<${#line[*]};i++))        # перебираем слова в строке
    do
      s=$[$n+${#line[i]}]                # устанавливаем расчетную длину подстроки со следующим словом
      if [ $s -ge $line_width ]          # проверяем соответствие расчетной длины подстроки условию
      then
        k=0                              # сбрасываем счетчик слов подстроки
        while [ $n -lt $line_width ]     # проверяем соответствие длины подстроки условию
        do
          l[k]="${l[k]} "                # добавляем пробел к одному слову подстроки
          n=$[$n+1]                      # увеличиваем длину подстроки (добавили пробел)
          if [ $[++k] -lt ${#l[*]} ]     # проверяем достигнуто ли последнее слово подстроки
          then
            k=0                          # начинаем форматирование подстроки с её 1-го слова
          fi
        done
        my_print                         # выводим подстроку на экран
        unset l                          # обнуляем массив подстроки
        n=$[${#line[i]}+1]               # устанавливаем длину новой подстроки = следующее слово + пробел
      else
        n=$[$s+1]                        # приравниваем расчетную длину фактической + длину пробела
      fi
      l[${#l[*]}]=${line[i]}             # добавляем к массиву подстроки следующее слово
    done
    my_print                             # выводим на экран последнюю (неполную) подстроку
  else
    echo "${line[*]}"                    # выводим на экран пустую строку (если она была в тексте)
  fi
done

Можно конечно второй массив и не делать, но код более запутанный становится. Хотя если осуществлять другой алгоритм форматирования (например пробел с начала, потом пробел с конца) то может и будет иметь смысл.
« Последнее редактирование: 15 Октября 2014, 11:28:37 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

 

Страница сгенерирована за 0.017 секунд. Запросов: 21.