在printf中填充字符

我正在编写一个bash shell脚本来显示一个进程是否正在运行。

到目前为止,我在这里。

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

这给了我一个输出,如:

 JBoss [DOWN] GlassFish [UP] verylongprocessname [UP] 

我想用“ – ”或“*”填充两个字段之间的空白,以使其更具可读性。 我怎样才能做到这一点,而不会干扰领域的一致?

我想要的输出是:

 JBoss ------------------------------------------- [DOWN] GlassFish --------------------------------------- [UP] verylongprocessname ----------------------------- [UP] 

纯Bash,没有外部公用事业

这个演示做了充分的理由,但是如果你想要粗糙的线条,你可以省略减去第二个string的长度。

 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 

不幸的是,焊盘string的长度必须被硬编码,但是焊盘长度可以是一个variables,如图所示。

输出:

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

不减去第二个string的长度:

 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" 

纯粹的打击。 使用'PROC_NAME'的值的长度作为固定string'line'的偏移量:

 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] 

琐碎(但工作)的解决scheme:

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

说明:

  • printf '\055%.0s' {1..40} – 创build40个破折号
    (破折号被解释为选项,所以使用转义ascii代码)
  • "$PROC_NAME ..." – 连接$ PROC_NAME和破折号
  • | head -c 40 | head -c 40 – 修剪string到前40个字符

没有办法使用printf填充空格而不是空格。 你可以使用sed

 printf "%-50s@%s\n" $PROC_NAME [UP] | sed -e 's/ /-/g' -e 's/@/ /' -e 's/-/ /' 

这个更简单,不需要外部命令。

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

我认为这是最简单的解决scheme。 纯壳build立,没有内联math。 它借鉴了以前的答案。

只是子string和$ {#…}元variables。

 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 

只使用echo

@Dennis Williamson的工作人员工作得很好,除了我试图用echo来做这件事。 回声允许输出特定颜色的charcacters。 使用printf将删除该着色并打印不可读的字符。 这里是echo唯一的select:

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

输出:

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

当然,您可以使用@Dennis Williamson提出的所有变体,无论您想要将右部分左alignment还是右alignment(用25 - ${#string1}replace25 - ${#string1} - ${#string2}等等…

这是另外一个:

 $ { 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] 

如果你在一些固定的列号结束填充字符,那么你可以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"