URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10062
[ Назад ]

Исходное сообщение
"Не получается создать переменную, из одних пробелов"

Отправлено klok79 , 22-Дек-15 22:01 
Здравствуйте.
Не получается создать переменную, из одних пробелов
Задача состоит в том, чтобы в терминале (через Telnet) выводить заголовки перед каждым определенным действием.
Заголовок состоит из трех строк:
1 - 80 символов "="
2 - Произвольный текст, размещенный по центру окна терминала
3 - 80 символов "="
shell знаю не очень хорошо (Неделя прошла как начал изучать). Застрял на 2-м пункте.

Вот такой код функции работает корректно. Строка центрируется.
func_ShowHead() {
local sTab=$1; sLen=${#sTab}; local xS=0;    # Привычка из Delphi
if ! [ -z $1 ]; then                         # Если строка получена
    let "xS=80-$sLen"; let "xS=xS/2"         # Рассчитываю, сколько пробелов нужно
# вывести перед выводом полученной строки для её центрирования
    while [ "$xS" -gt "0" ]; do              # Столько раз в цикле  
        sTab="-"$sTab                        # !! добавляю вперед строки символ "-" !
        let "xS-=1"                          # уменьшаю счетчик
    done
fi
echo $sTab                                   # Вывожу ожидаемый результат
}

А если изменить символ "-" на пробел (что, собственно, и нужно) - строка не центрируется.
Вот такой код функции уже работает не корректно. Строка не центрируется.
func_ShowHead() {
local sTab=$1; sLen=${#sTab}; local xS=0;
if ! [ -z $1 ]; then
    let "xS=80-$sLen"; let "xS=xS/2"
    while [ "$xS" -gt "0" ]; do
        sTab=" "$sTab                        # !!! добавляю вперед строки пробел !!!
        let "xS-=1"
    done
fi
echo $sTab                                   # Вывожу не корректный результат
}

Вызов функции: func_ShowHead "Произвольный текст."
Пробовал заполнять строку символами, а потом заменять и на пробелы функцией tr - тоже не работает.
Даже не знаю, как обмануть интерпретатор. Он, видимо считает пробел ложью и замещает его на null.
Может кто знает более элегантное решение ???
Пишу на Федоре 6 для linux 2.6.6
Спасибо


Содержание

Сообщения в этом обсуждении
"Не получается создать переменную, из одних пробелов"
Отправлено кегна , 22-Дек-15 23:32 
>[оверквотинг удален]
>   # Вывожу не корректный результат
> }
> Вызов функции: func_ShowHead "Произвольный текст."
> Пробовал заполнять строку символами, а потом заменять и на пробелы функцией tr
> - тоже не работает.
> Даже не знаю, как обмануть интерпретатор. Он, видимо считает пробел ложью и
> замещает его на null.
> Может кто знает более элегантное решение ???
> Пишу на Федоре 6 для linux 2.6.6
> Спасибо

Пробелы нужно экранировать вот так '\ '


"Не получается создать переменную, из одних пробелов"
Отправлено klok79 , 23-Дек-15 09:50 
> Пробелы нужно экранировать вот так '\ '

Да пробовал я экранировать - строка создается из обратных слэшэв и пробелов. Может какой символ пропускал, может двойными кавычками, не знаю. Вечером попробую. Спасибо.
Тема еще не закрыта.


"Не получается создать переменную, из одних пробелов"
Отправлено Имя , 23-Дек-15 09:48 
space='                  word';
Сравните:
1) echo $space
word
2) echo "$space"
                  word

POSIX, Word Expansions.
If the complete expansion appropriate for a word results in an empty field, that empty field shall be deleted from the list of fields that form the completely expanded command, unless the original word contained single-quote or double-quote characters.


"Не получается создать переменную, из одних пробелов"
Отправлено Andrey Mitrofanov , 23-Дек-15 09:55 
> Может кто знает более элегантное решение ???
> Пишу на Федоре 6 для linux 2.6.6
> Спасибо

Ну, на.  Пишу на баше...

#!/bin/bash

func_ShowHead() {
    local xS
    let "xS=(80-${#1})/2"  "${#1}==0 || xS<0" \
        && xS=0
    printf '%*s%s\n' $xS '' "$1"
}

for i in 0 `seq 8 9 89`; do
    [ $i = 0 ] &&  str= ||  str="$(printf '<%*s>' $i '' |tr \  -)"
    echo "$i +$(func_ShowHead "$str")+"
done



"Не получается создать переменную, из одних пробелов"
Отправлено klok79 , 23-Дек-15 10:22 
>[оверквотинг удален]
>     local xS
>     let "xS=(80-${#1})/2"  "${#1}==0 || xS<0" \
>         && xS=0
>     printf '%*s%s\n' $xS '' "$1"
> }
> for i in 0 `seq 8 9 89`; do
>     [ $i = 0 ] &&  str=
> ||  str="$(printf '<%*s>' $i '' |tr \  -)"
>     echo "$i +$(func_ShowHead "$str")+"
> done

Мне это пока слишком для понимания. Но выглядит классно. Спасибо. Буду разбираться. Вечером отпишусь.


"Не получается создать переменную, из одних пробелов"
Отправлено erera22 , 24-Дек-15 16:33 
Все гораздо проще.

Чтобы вывести текст в центре строки, надо:
1. найти всю длину строки ($cols);
2. поделить длину всей стройки на 2, чтобы узнать центр ($tcenter);
3. прибавить к $tcenter половину длины строки с текстом ($text)

# full line length
cols=$(tput cols)
# my text
text="This is a test text"

# calculating center of line
tcenter=$(($cols/2))
# calculating shift using $tcenter and halt of text length
tshift=$(($tcenter+${#text}/2))

# making output
printf "%${tshift}s\n" "$text"


"Не получается создать переменную, из одних пробелов"
Отправлено klok79 , 24-Дек-15 22:30 
Спасибо всем огромное за ответы с примерами.
Я хотя и не понял выражение  (printf "%${tshift}s\n"), но последний пример:
cols=80
text="This is a test text"
tcenter=$(($cols/2))
tshift=$(($tcenter+${#text}/2))
printf "%${tshift}s\n" "$text"
у меня заработал.
А этот пример
func_ShowHead() {
    local xS
    let "xS=(80-${#1})/2"  "${#1}==0 || xS<0" \
        && xS=0
    printf '%*s%s\n' $xS '' "$1"
}

for i in 0 `seq 8 9 89`; do
    [ $i = 0 ] &&  str= ||  str="$(printf '<%*s>' $i '' |tr \  -)"
    echo "$i +$(func_ShowHead "$str")+"
done
я так и не смог выполнить. Показывает ошибку синтаксиса - преждевременное окончание файла. Трудно править синтаксис когда не вижу малейшего смысла в символах.
Надеюсь, со временем я смогу понять что все это значить

Еще раз СПАСИБО всем откликнувшимся на мой SOS. Тему можна считать закрытой.


"Не получается создать переменную, из одних пробелов"
Отправлено Andrey Mitrofanov , 25-Дек-15 09:56 
> Я хотя и не понял выражение
> printf "%${tshift}s\n" "$text"
> у меня заработал.
> А этот пример

#!/bin/bash

Не пропустил? И _в исполняемый файл_ положил?  И да, допускаю, что могда не подойти даже версия баша. Впрочем, у меня работает, и ладно.

> func_ShowHead() {
> я так и не смог выполнить. Показывает ошибку синтаксиса - преждевременное окончание
> файла. Трудно править синтаксис когда не вижу малейшего смысла в символах.

Ну, и ладненько. Лобиться, чтоб они ещё и %) исполнялись -- и можно основывать Культ Баша.

> Надеюсь, со временем я смогу понять что все это значить

Только если будешь этим (шелом, не пониманием, да) заниматься профессионально, фулЬ-тайм.


"Не получается создать переменную, из одних пробелов"
Отправлено erera22 , 25-Дек-15 14:46 
Синтаксис printf: %<кол-во символов><тип переменной>.
В нашем случае:
% - спец символ
<кол-во символов> == ${#tshift} (это величина, она же длина, сдвига вправо)
s - выводить будем строковое значение

То есть при ${#tshift} == 80 получим:
printf "%80s" "Foo" - вывести текст Foo со сдвигом вправо на 80 символов.