Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Transform string to the same number of hyphens

49 views
Skip to first unread message

John Gray

unread,
Aug 23, 2017, 8:32:47 AM8/23/17
to
For "underlining" purposes I want to transform a single word, replacing each letter by an equals sign or perhaps a hyphen.

I can do this via a looping mechanism, letter by letter, but is there a more elegant method requiring one or just a few lines?

set original=SingleWord
transforms to
set underline=----------

JJ

unread,
Aug 23, 2017, 10:45:22 AM8/23/17
to
I don't think so. If you're aiming for easy programming, make the loop as a
function so that you can call it in just a single line. e.g.

@echo off
setlocal enabledelayedexpansion

set str=abc
echo Before=%str%
call :replace
echo After =%str%

set str=def
echo Before=%str%
call :replace
echo After =%str%

goto :eof

:replace
for /l %%A in (0,1,99) do (
set c=!str:~%%A,1!
if "!c!" == "" goto next
call :replacechr !c!
)
:next
goto :eof
:replacechr
set str=!str:%1=-!

John Gray

unread,
Aug 24, 2017, 5:58:40 AM8/24/17
to
Thanks, some neat tricks there.
I have refined my attempt to make it more general, and present two possible methods:

@echo off
setlocal
:: from a header string which contains no double quotes or poison characters
:: construct an underlines string of the same length
:: the header string
set hdr=My Page Header
:: index into header string, first character initially
set idx=0
:: the underlines string, null initially
set uls=
:: the underlining character: one of - = * # (say)
set ulchr=*
::--------------------
:loop
rem extract the current character from the header string
call set chr=%%hdr:~%idx%,1%%
if "%chr%" neq "" (
set "uls=%uls%%ulchr%"
set /a idx+=1
goto loop
)
::--------------------
echo %hdr%
echo %uls%
PAUSE
::===========================================================
:: another method, by truncating a copy of the header string
set tmp=%hdr%
set uls=
set ulchr==
:--------------------
:loop1
rem truncate right until there is no character remaining
call set tmp=%%tmp:~0,-1%%
set "uls=%uls%%ulchr%"
if defined tmp goto loop1
::--------------------
echo %hdr%
echo %uls%
PAUSE
endlocal

ada...@poczta.onet.pl

unread,
Aug 24, 2017, 7:10:31 AM8/24/17
to
W dniu środa, 23 sierpnia 2017 14:32:47 UTC+2 użytkownik John Gray napisał:
> For "underlining" purposes I want to transform a single word, replacing each letter by an equals sign or perhaps a hyphen.
>

@echo off

set INPUT=Text to underline


set XX=%INPUT%
:loop
SET XX=%XX:~1%
SET UND=%UND%-

IF NOT "%XX%"=="" GOTO loop

echo %INPUT%
echo %UND%

pro...@berkeley.edu

unread,
Aug 24, 2017, 1:07:20 PM8/24/17
to
Here's another variation (screen capture Win7 Pro):

>set filename=c:\cmd\demo\hyphenator.cmd

>listit %filename%
==========begin "c:\Cmd\demo\hyphenator.cmd" ==========
1. @echo off & setlocal enableextensions enabledelayedexpansion
2. >%temp%\$eraseme$.$$$ echo/%*
3. for %%a in (%temp%\$eraseme$.$$$) do (
4. set /a length=%%~za-2
5. del %%a
6. )
7. set $O=
8. for /l %%i in (1,1,%length%) do set $O=!$O!-
9. endlocal&set %~n0=%$O%&echo/%*&echo/%$O%
==========end "c:\Cmd\demo\hyphenator.cmd" ==========

>%filename% supercalifragilisticexpialwhatever
supercalifragilisticexpialwhatever
----------------------------------

>for %a in (%filename%) do @set %~na
hyphenator=----------------------------------

end screen capture Win7 Pro

--
Phil Robyn

Herbert Kleebauer

unread,
Aug 25, 2017, 4:37:39 AM8/25/17
to
On 23.08.2017 14:32, John Gray wrote:

> I can do this via a looping mechanism, letter by letter, but is there
> a more elegant method requiring one or just a few lines?
>
> set original=SingleWord
> transforms to
> set underline=----------

Slow but short:

@echo off
set original=Single Word
echo %original%

for /l %%i in (1,1,32) do call set original=%%original:~1%%-

echo %original%


John Gray

unread,
Aug 25, 2017, 6:35:16 AM8/25/17
to
Phil: I've added that method to my file of solutions, even though I prefer to avoid temporary files.

Herbert: your method can suffer from "the trailing blank problem" (certainly using NOTEPAD) unless in each SET statement you enclose everything after SET in double-quotes (or otherwise). Presumably this is editor-dependent?
Interesting that the FOR loop terminates early!

Perhaps:

(set original=Single Word)

Herbert Kleebauer

unread,
Aug 25, 2017, 8:34:34 AM8/25/17
to
On 25.08.2017 12:35, John Gray wrote:

> Herbert: your method can suffer from "the trailing blank problem"
> (certainly using NOTEPAD) unless in each SET statement you enclose
> everything after SET in double-quotes (or otherwise).

I don't think this is a "problem". If you write a trailing space,
then the batch can't just ignore it. But you always can add a &
to ignore unwanted trailing spaces:

for /l %%i in (1,1,32) do call set original=%%original:~1%%-&

> Interesting that the FOR loop terminates early!

The "for" doesn't terminate early, but replacing a "-" by an
other "-" doesn't change anything. But there is a problem if you
don't know the upper limit for the length of the word. In this
case you have to check and loop if necessary:

@echo off
set original=Single Word
echo %original%

:loop
for /l %%i in (1,1,32) do call set original=%%original:~1%%-&
set a=%original:-=%&if defined a goto :loop

echo %original%


But then you also can set the loop count in the for loop to 1
(which means removing the for loop):

@echo off
set original=Single Word
echo %original%

:loop
set original=%original:~1%-&set a=%original:-=%&if defined a goto :loop

echo %original%

mokomoji

unread,
Sep 4, 2017, 10:07:57 AM9/4/17
to
2017년 8월 24일 목요일 오후 8시 10분 31초 UTC+9, ada...@poczta.onet.pl 님의 말:
good..

@echo off
setlocal
set "z_original=original=Single Word sdfasdf23423423423424242dsfasdas3424234"
set "z_o2=%z_original%"
:l
set "z_o2=%z_o2:~1%"
set "z_u2=%z_u2%-"
if "%z_o2%" neq "" goto :l

echo %z_original%
echo %z_u2%
endlocal

pause
0 new messages