2010-12-10 3 views
78

Я пишу сценарий оболочки bash для отображения, если процесс запущен или нет.Заполнение символов в printf

До сих пор я получил это:

printf "%-50s %s\n" $PROC_NAME [UP] 

код дает мне этот выход:

JBoss            [DOWN] 

GlassFish           [UP] 

verylongprocessname        [UP] 

Я хочу раздуть разрыв между этими двумя областями с «-» или «* 'чтобы сделать его более читаемым. Как это сделать, не нарушая выравнивание полей?

Выход я хочу это:

JBoss ------------------------------------------- [DOWN] 

GlassFish --------------------------------------- [UP] 

verylongprocessname ----------------------------- [UP] 

ответ

12

Trivial (но работает) решение:

echo -e "---------------------------- [UP]\r$PROC_NAME " 
+4

Но только на терминале. Если вывод отправляется в файл, это будет беспорядок. – thkala 2010-12-10 13:53:33

+3

так что вы действительно ожидаете от тривиального решения?!? полная работа также с перенаправлением вывода?!? ]: P – 2010-12-10 13:56:19

8

Там нет никакого способа прокладки с ничего, кроме пространства с помощью printf. Вы можете использовать sed:

printf "%[email protected]%s\n" $PROC_NAME [UP] | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /' 
+7

+1 Существует проблема, если PROC_NAME содержит тире - легко разрешается с помощью дополнительного @: `printf"% -50s @% s \ n "$ {PROC_NAME} @ [UP] | sed -e 's// -/g' -e 's/- @//' -e 's/@ -//' ` – thkala 2010-12-10 14:14:51

2

Вот еще один:

$ { echo JBoss DOWN; echo GlassFish UP; } | while read PROC STATUS; do echo -n "$PROC "; printf "%$((48-${#PROC}))s " | tr ' ' -; echo " [$STATUS]"; done 
JBoss -------------------------------------------- [DOWN] 
GlassFish ---------------------------------------- [UP] 
54

Pure Bash, никаких внешних утилит

Эта демонстрация имеет полное оправдание, но вы можете просто опускаем вычитания длины вторая строка, если вы хотите оборванных правых линий.

pad=$(printf '%0.1s' "-"{1..60}) 
padlength=40 
string2='bbbbbbb' 
for string1 in a aa aaaa aaaaaaaa 
do 
    printf '%s' "$string1" 
    printf '%*.*s' 0 $((padlength - ${#string1} - ${#string2})) "$pad" 
    printf '%s\n' "$string2" 
    string2=${string2:1} 
done 

К сожалению, длина строки площадки должна быть жестко, но padlength может быть переменной, как показано на рисунке.

Выход:

a--------------------------------bbbbbbb 
aa--------------------------------bbbbbb 
aaaa-------------------------------bbbbb 
aaaaaaaa----------------------------bbbb 

Без вычитания длины второй строки:

a---------------------------------------bbbbbbb 
aa--------------------------------------bbbbbb 
aaaa------------------------------------bbbbb 
aaaaaaaa--------------------------------bbbb 

Первая строка может вместо того, чтобы быть эквивалентом (по аналогии с sprintf):

printf -v pad '%0.1s' "-"{1..60} 

Вы можете распечатать все на одной линии, если хотите:

printf '%s%*.*s%s\n' "$string1" 0 $((padlength - ${#string1} - ${#string2})) "$pad" "$string2" 
+1

Не могли бы вы немного объяснить printf '% *. * s' ... часть ? – 2013-03-22 11:33:34

+1

@EdouardLopez: первая звездочка заменяется нулем в списке аргументов. Вторая звездочка заменяется результатом вычисления во втором аргументе. Например, для строк «aaaa» и «bbbbb», например, ``% 0.31s'`. Строка (окончательный аргумент) усекается до длины, указанной после точки. Ноль препятствует выходу пространственного дополнения. Таким образом выводятся 31 дефис. – 2013-03-22 14:07:42

44

Pure Bash.Используйте длину значения «proc_name», как смещение для фиксированной строки «линии»:

line='----------------------------------------' 
PROC_NAME='abc' 
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}" 
PROC_NAME='abcdef' 
printf "%s %s [UP]\n" $PROC_NAME "${line:${#PROC_NAME}}" 

Это дает

abc ------------------------------------- [UP] 
abcdef ---------------------------------- [UP] 
1

Если вы заканчиваете символы колодки на фиксированное количество столбцов, то вы можете overpad и cut по длине:

# Previously defined: 
# PROC_NAME 
# PROC_STATUS 

PAD="--------------------------------------------------" 
LINE=$(printf "%s %s" "$PROC_NAME" "$PAD" | cut -c 1-${#PAD}) 
printf "%s %s\n" "$LINE" "$PROC_STATUS" 
3

использованием echo только

Anwser of @Dennis Williamson работает отлично, за исключением того, что я пытался сделать это с помощью эха. Echo позволяет выводить символы с определенным цветом. Использование printf удалит эту раскраску и напечатает нечитаемые символы. Вот echo -только альтернатива:

string1=abc 
string2=123456 
echo -en "$string1 " 
for ((i=0; i< (25 - ${#string1}); i++)){ echo -n "-"; } 
echo -e " $string2" 

выход:

abc ---------------------- 123456 

, конечно, вы можете использовать все варианты, предложенные @Dennis Уильямсон, хотите ли вы правую часть, чтобы быть лево- или выравнивание по правому краю (замена 25 - ${#string1} на 25 - ${#string1} - ${#string2} и т.д. ...

8
echo -n "$PROC_NAME $(printf '\055%.0s' {1..40})" | head -c 40 ; echo -n " [UP]" 

Объяснение:

  • printf '\055%.0s' {1..40} - Создание 40 черточки
    (тир интерпретируются как вариант, так использование спаслось ASCII код вместо)
  • "$PROC_NAME ..." - Объединить $ proc_name и мчится
  • | head -c 40 - Обрезать строку первых 40 символов
6

Это еще проще и не выполняет внешних команд.

$ PROC_NAME="JBoss" 
$ PROC_STATUS="UP" 
$ printf "%-.20s [%s]\n" "${PROC_NAME}................................" "$PROC_STATUS" 

JBoss............... [UP] 
8

Я думаю, что это самое простое решение. Чистые оболочки, нет встроенной математики. Он заимствует предыдущие ответы.

Просто подстроки и мета-переменная $ {# ...}.

A="[>---------------------<]"; 

# Strip excess padding from the right 
# 

B="A very long header"; echo "${A:0:-${#B}} $B" 
B="shrt hdr"   ; echo "${A:0:-${#B}} $B" 

Производит

[>----- A very long header 
[>--------------- shrt hdr 


# Strip excess padding from the left 
# 

B="A very long header"; echo "${A:${#B}} $B" 
B="shrt hdr"   ; echo "${A:${#B}} $B" 

Производит

-----<] A very long header 
---------------<] shrt hdr 
Смежные вопросы