2010-12-10 133 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