1

I'm working in Bash. I'm trying to get a particular variable to always be the same length, 16 characters long, regardless what is passed into it.

I tried

t=33455
until [[ ${#t} == 16 ]]; do
t="${t} "
done

but it seems to run forever. It would seem that the spaces aren't treated as characters.

Is there any way to get the variable to always be 16 characters long?

EDIT: I forgot to include an important bit of context. I updated the code to reflect. None of the variables that will be put in are more than 6 digits initially. When I do the above, it runs infinitely.

4
  • 3
    works for me: perhaps your variable started out longer than 16. You might want to replace that == with -ge. Feb 15 '16 at 21:02
  • Echoing the variable in the loop while you are developing your script would tell you exactly what is going on.
    – Anthon
    Feb 15 '16 at 21:23
  • careful about using echo to print the contents -- try printf to confirm
    – Jeff Schaller
    Feb 15 '16 at 21:35
  • Spaces are treated as characters like any other. Add set -x at the top of the script (just below the #!/bin/bash line) to see what's going on. Feb 15 '16 at 22:39
2

As for the issue at hand I guess Dickey is on the track.

As for an alternative, perhaps use something like:

t="$(printf "%-16.16s" "$t")"

If t is always shorter then 16, which you have to be completely sure of, you could do:

t="$(printf "%-16s" "$t")"

Note that it will crash on non-ASCII characters. For example, test:

$ x=123
$ x="$(printf "%-16.16s" "$x")"
$ printf "|%s|\n|1234567890123456|789012\n" "$x"
|123             |
|1234567890123456|789012

$ x=12345678901234567890123456
$ x="$(printf "%-16.16s" "$x")"
$ printf "|%s|\n|1234567890123456|789012\n" "$x"
|1234567890123456|
|1234567890123456|789012

$ x=sadasdæøåsasd
$ x="$(printf "%-16.16s" "$x")"
$ printf "|%s|\n|1234567890123456|789012\n" "$x"
|sadasdæøåsasd|                                     <<<--- ups!
|1234567890123456|789012

( Or the more fancy:

printf "\e[41m%s\e[0m\n\e[41m1234567890123456\e[0m789\n" "$x"

)

2
  • A precision component can elaborate the %-16s specification so that it also truncates: printf %-16.16s '1234567890123456|7890' Feb 16 '16 at 0:07
  • Been working with unix systems for almost a year now and I've somehow managed to never hear about printf...
    – mkingsbu
    Feb 16 '16 at 14:59
1

If your variable started out too long, it will never get smaller. This works for me (truncate the string, or pad it):

if [[ ${#t} -gt 16 ]]
then
    t="${t:0:16}"
else
    until [[ ${#t} -ge 16 ]]
    do
        t="${t} "
    done
fi

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.