2010-12-10 130 views
78

我正在编写一个bash shell脚本来显示进程是否正在运行。printf中的填充字符

到目前为止,我得到这个:

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

的代码给了我这样的输出:

JBoss            [DOWN] 

GlassFish           [UP] 

verylongprocessname        [UP] 

我要垫一两个领域之间的差距“ - ”或“* '使其更具可读性。我如何做到这一点,而不会干扰领域的一致性?

我想输出是:

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

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

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

回答

12

平凡的(但工作)解决方案:

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

纯猛砸,无需外接公用事业

该演示也有充足的理由,但你可以省略减去的长度第二个字符串,如果你想要粗糙的线条。

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 

不幸的是,pad字符串的长度必须被硬编码,但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

+0

这个页面可以帮助你理解@丹尼斯威廉姆森回答:http://wiki.bash-hackers.org/commands/builtin/printf#modifiers – 2013-03-23 09:54:21

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] 
+5

我不明白_... **但是** _I喜欢它.. 。 – 2014-06-11 15:57:03

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

@Dennis Williamson的anwser工作得很好,除了我试图用echo来做到这一点。 Echo允许输出特定颜色的charcacters。使用printf将删除该着色并打印不可读的字符。这里的echo -only替代:

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

输出:

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

当然你可以使用你是否希望右半部分是左对齐或右对齐由@Dennis威廉姆森提出的所有变化(由25 - ${#string1} - ${#string2}等替代25 - ${#string1} ...

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个字符
+0

聪明的aproach +1。 – 2015-07-08 18:11:52

+0

非常好,谢谢。这很聪明。 – Robert 2016-03-15 14:03:40

+0

奇怪的是,当我做'printf'x'{1..40}'时,它只打印单个'x' hmmm – Krystian 2018-01-12 14:24:49

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