Home > Back-end >  Batch program - delete all dividing symbols in numbers
Batch program - delete all dividing symbols in numbers

Time:09-01

I have a homework task which needed to be done using just batch script. I need to rewrite all the numbers in .txt file if they have dividing symbols . or , but those strings may contain both words and numbers. Also the result should stay in the same file.

For example:

Lorem ipsum dolor 12.3254
2556,4646 ex commodo

would become

Lorem ipsum dolor 123254
25564646 ex commodo

I started with some code that looks like this:

@echo off
setlocal EnableDelayedExpansion

SET verfile=%1

FOR /f "tokens=* delims= " %%A IN (%verfile%) DO (
    SET "Var=%%A"    
    FOR /l %%i IN (0, 1, 9) DO (    
        echo !Var! | findstr "."     
        IF %ERRORLEVEL% EQU 0 (

    )
)

And now I have no idea how to continue it.

Can you help me please?

CodePudding user response:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
rem The following settings for the source directory and filename are names
rem that I use for testing and deliberately include names which include spaces to make sure
rem that the process works using such names. These will need to be changed to suit your situation.

SET "sourcedir=u:\your files"
SET "filename1=%sourcedir%\q73553463.txt"

:: remove variables starting #
FOR  /F "delims==" %%b In ('set # 2^>Nul') DO SET "%%b="

SET /a linecount=0

:: Read entire file into memory

FOR /f "usebackqdelims=" %%e IN ("%filename1%") DO (
 rem next line number
 SET /a linecount  =1
 rem record in memory
 SET "#!linecount!=%%e"
)

:: process each line removing [,.] following a digit
:: and report to original file
(
FOR /L %%e IN (1,1,%linecount%) DO (
 FOR %%c IN ("." ",") DO FOR /L %%y IN (0,1,9) DO SET "#%%e=!#%%e:%%y%%~c=%%y!"
 ECHO !#%%e!
)
)>"%filename1%"

TYPE "%filename1%"

GOTO :EOF

The set # command will generate a list like

#whatever=something
#whateverelse=somethingelse

for all variables that are currently set and start #.BUT it would be unusual to have any variable set that starts # so set would generate an error. The 2^>nul sends any error-report (on standard device stderr, which is device 2) to nul that is, nowhere. The caret ^ is required because cmd needs to distinguish between a part of the set command and a part of the for.

The for/f...%%b using delims of = generates "tokens" from the list generated by the set. Tokens are separated by any sequence of any of the delimiters specified between = and ", and by default, "token1" is selected, so the strings applied to %%b are

#whatever
#whateverelse

and these variables need to be set to nothing.

See for /? from the prompt for documentation on for or browse thousands of examples on SO.

Use set "var=value" for setting string values - this avoids problems caused by trailing spaces which can cause chaos. Once bitten, twice shy.

Then we read the file. Using "delims=" sets no delimiters, hence the whole line forms "token 1" which is assigned to %%e. The usebackq changes the meaning of " so that a double-quoted filename may be used. The filename I've used includes a Space but if there are no separator characters in the name, the quotes and usebackq can be omitted (again, ref for/?)

Then add 1 to the linecount and record the line in memory by assigning it to #!linecount!. The !linecount! is required because linecount is varying within the block (parenthesised sequence of lines) - and with delayedexpansion enabled, %linecount% yields the value when the block was encountered, and !linecount! the run-time or instantaneous value - as it changes within the block.

Stephan's DELAYEDEXPANSION link

So - having established #1, #2..#%linecount% with the lines from the file, we can process those variables and produce a replacement file.

Note that there is a block formed by ( for...%%e...)>filename. This allows any echoed data within the block to be redirected to the file. > redirects to a new version whereas >> would append to any existing file.

So - we iterate through all of the #linenumber lines using a for /L on %%e. For each of these, we set %%c to "." and %%y to 0 to 9 and then replace any string %%y%%c with %%y (3. gets replaced by 3 for example). Then repeat with %%c set to ",". set /? provides documentation and browsing SO examples.

But Woah, Neddie! There's a little trick here. , is a list-separator so (. ,) won't work - it will be treated as (.). Using the quotes allows cmd to read each character separately, and we need to use %%~c instead of %%c to dump the quotes.

So - take a look around. You can do a lot with batch if you're devious enough. And no doubt you'll be challenged if you present this solution. Be ready to explain it. A really good way to follow what's happening is to turn echo on and watch the magic step-by-step. Use pause liberally and perhaps remove the >"%filename1%" to prevent the report going to the file while you're observing what's happening.

CodePudding user response:

@echo off
setlocal enabledelayedexpansion

set "verfile=%~1"

echo before:
type "%verfile%"

for /f "usebackq tokens=*" %%a in ("%verfile%") do (
    set strline=%%a
    set strline=!strline:.=!
    set strline=!strline:,=!
    echo !strline!>>"%verfile%.tmp"
)

echo.
echo after:
type "%verfile%.tmp"
del /f /q "%verfile%.tmp"
  • Related