It seems like a fairly simple task, yet I can't find a fast and reliable solution to it.
I have strings in bash, and I want to know the number of characters that will be printed on the terminal. The reason I need this, is to nicely align the strings in three columns of n characters each. For that, I need to add as many "space" as necessary to make sure the second and third columns always starts at the same location in the terminal.
Example of problematic string length:
v='féé'
echo "${#v1}"
> # 5 (should be 3)
printf '%s' "${v1}" | wc -m
> # 5 (should be 3)
printf '%s' "${v1}" | awk '{print length}'
> # 5 (should be 3)
The best I have found is this, that works most of the time.
echo "${v}" | python3 -c 'v=input();print(len(v))'
> # 3 (yeah!)
But sometimes, I have characters that are modified by the following sequences. I can't copy/past that here, but this is how it looks like:
v="de\314\201tresse"
echo "${v}"
> # détresse
echo "${v}" | python3 -c 'v=input();print(len(v))'
> # 9 (should be 8)
I know it can be even more complicated with \r character or ANSI sequences, but I am only going to have to deal with "regular" strings that can be commonly found in filenames, documents and other file content writing by humans. Since the string IS printed in the terminal, I guess there must be some engine that knows or can know the printed length of the string.
I have also considered the possible solution of sending ANSI sequence to get the position of the cursor in the terminal before and after printing the string, and use the difference to compute the length, but it looks like a rabbit hole I don't want to dig. Plus it will be very slow.
echowill add a newline so the output ofecho 'foo'is 4 characters long, not 3 as you might expect. You could useprintf '%s' 'foo'instead but then the output is no longer a valid text "file" since it doesn't have a terminating newline so YMMV with what any text processing tool does with it so - read the man page for whatever tool you use to determine the length if you go that route rather than just subtracting 1.input()in Python removes the newline.féélooks like three characters, but thoseé's are note's. It takes two bytes to print that one character, though if you print out the individual bytes, one looks like ane, and the other doesn't generally print, since it's an "overstrike". Be super careful in your terminology - and I bet I botched mine here somewhere, lol. Tricky!