Page 1 of 1

Substring operations don't work with spaces?

Posted: 2021-Jul-26, 7:48 am
by MigrationUser
22 Feb 2021 10:47
Rekrul


I'm writing a routine to reformat numbers to include commas as dividers and I've run into something odd;

Code: Select all

@echo off

set size=1234
set size=xxxxxxxxxxxx%size%
echo %size:~-9,-6%

set size=1234
set size=            %size%
echo %size:~-9,-6%
The first one prints "xxx" as it should. The second prints "ECHO is off"

Spaces aren't considered a valid part of a string? If I Echo Size, it shows the spaces just fine. What am I missing here?

Explanation: I want all the numbers to be right-justified so that they'll line up neatly. I pad the start with 12 characters in case the number is as small as a single digit. I was then trying to cut the string apart into hundreds, thousands, millions, billions, etc, test each to see if it's blank and if not, add a comma after it, then put the parts back together and truncate the string to the last 13 characters. This would give me the number, comma separated with enough padding to make sure that even single digit numbers line up correctly (with a mono-spaced font).

I know I can use Xs and then search/replace them to spaces (at least I SHOULD be able to do that), but I'd like to know why you can't echo a substring composed of spaces.

----------------------------

#2 22 Feb 2021 13:02
bluesxman


I think the substring is working just fine, it's the use of "echo" that's the issue here.

If I'm reading your substring right, you are cutting into "size" at the offset 9 characters from the end and stopping at offet 6 from the end.

Your value of "size" is only 4 characters long, so you're just extracting white space (your "xxx" example seems to confirm my reading).

So you are effectively running "echo" with no actual parameter (just the white space delimiter), under those circumstances the default action is to print the current setting for "echo", as you are seeing.

You'd get the same with a naked "echo" or the syntactically identical "echo " on a line.

See the "Echo a variable" section here:

https://ss64.com/nt/echo.html

There has been some prior discussion about which character is best to use.
viewtopic.php?f=2&t=34

Personally, I've always used colon as per the linked page, and I do this for every single instance of "echo" (where I'm not trying to turn it on or off) by force of decades of habit.

Last edited by bluesxman (26 Feb 2021 21:15)

cmd | *sh | ruby | chef

----------------------------

#3 22 Feb 2021 20:44
Rekrul
bluesxman wrote:

I think the substring is working just fine, it's the use of "echo" that's the issue here.

If I'm reading your substring right, you are cutting into "size" at the offset 9 characters from the end and stopping at offet 6 from the end.

Your value of "size" is only 4 characters long, so you're just extracting white space (your "xxx" example seems to confirm my reading).

So you are effectively running "echo" with no actual parameter (just the white space delimiter), under those circumstances the default action is to print the current setting for "echo", as you are seeing.
You'd get the same with a naked "echo" or the syntactically identical "echo " on a line.

I keep forgetting that Batch variables aren't really variables, but rather placeholders for whatever contents they contain. I keep thinking that putting something inside a variable insulates it and tells the script to treat it as just a line of text, rather than replacing it with the exact contents as if you had typed that line from scratch.

In fact, until this moment I didn't realize that you could use a full command as the definition for a variable, then put the variable name on a line by itself and the script will execute whatever command it contains.
bluesxman wrote:

See the "Echo a variable" section here:

https://ss64.com/nt/echo.html

There has been some prior discussionabout which character is best to use.
viewtopic.php?id=2086
Thanks for the links.
bluesxman wrote:

Personally, I've always used colon as per the linked page, and I do this for every single instance of "echo" (where I'm not trying to turn it on or off) by force of decades of habit.
I guess it's not the best practice, but I typically just use Echo by itself, unless I need a blank line, in which case I normally use "Echo.". I usually only do something different if I run into problems.

BTW, here's my routine for formatting numbers;

Code: Select all

:Format-Size
set Size=           %Size%

set GB=%Size:~-12,-9%
set MB=%Size:~-9,-6%
set KB=%Size:~-6,-3%
set BY=%Size:~-3%

if not "%GB%"=="   " set GB=%GB%,
if not "%MB%"=="   " set MB=%MB%,
if not "%KB%"=="   " set KB=%KB%,

set Size=   %GB%%MB%%KB%%BY%
set Size=%Size:~-15%
exit /b
I wrote it for reformatting file sizes, but it will work with any number up to 999 billion, adding commas and padding the start with enough spaces to ensure that all the numbers line up properly when viewed with a mono-spaced font. Of course someone else could probably come up with 2-3 lines of code that would do the same thing for any number up to 999 kajillion, but I'm not that good.

Originally, I was trying to test parts of the string by using substrings directly, but my numbers were off, so I switched to using Echo to just display them, which is where I encountered the problem. I finally realized that testing substrings was a huge PITA because the length of the string would change as commas were added so more tests were needed and the whole thing turned into a mess. This seemed easier.

----------------------------

#4 20 Mar 2021 07:16
T3RRY


Your issue can be resolved by using:

Echo(%size:~-9,-6%

See this dostips discussion for the history and reasoning involved in the use of this syntax: https://www.dostips.com/forum/viewtopic ... 74&start=0