120 votes

Rembourrage des caractères dans printf

J'écris un script shell bash pour afficher si un processus est en cours d'exécution ou non.

Jusqu'ici, je suis ici.

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

Cela me donne une sortie comme:

 JBoss                                              [DOWN]

GlassFish                                          [UP]

verylongprocessname                                [UP]
 

Je veux combler le fossé entre les 2 champs avec un '-' ou un * pour le rendre plus lisible. Comment puis-je faire cela sans perturber l'alignement des champs?

La sortie que je veux est:

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

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

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

85voto

Dennis Williamson Points 105818

Pur Bash, pas de utilitaires externes

Cette démonstration n'justification complète, mais vous pouvez tout simplement omettre la soustraction de la longueur de la deuxième chaîne, si vous voulez ragged-right lignes.

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

Malheureusement, la longueur du tampon de chaîne doit être codé en dur, mais l'padlength peut être une variable, comme indiqué.

Sortie:

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

Sans soustraire la longueur de la deuxième chaîne:

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

La première ligne pourrait être l'équivalent (similaire à l' sprintf):

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

Vous pouvez faire de l'impression sur une seule ligne si vous préférez:

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

74voto

fgm Points 5930

Pure Bash. Utilisez la longueur de la valeur de 'PROC_NAME' comme décalage pour la chaîne fixe 'ligne':

 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}}"
 

Cela donne

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

20voto

Nicola Leoni Points 146

Solution triviale (mais efficace):

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

15voto

F'x Points 6557

Il n’est pas possible de patiner avec autre chose que des espaces avec printf Vous pouvez utiliser sed :

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

2voto

thkala Points 36148

En voici un autre:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X