Search code examples
powershellbatch-filefor-loopvbscriptfind-replace

Find a number in text file and change signs for its row data using command line


I am learning batch scripting and the first task that came to me is a Text file that has more than 1000 rows and is something like this :

Organization, month,acct no.,data1,data2,data3,data4
orgA,Jan,1234,78900,78900,78900,78900

I need help in writing a batch file which should find a specific acct no. (for example: 3456) and put a '-' before data1, data2,data3,data4

I have tried : 1) using batch commands:

for /F "tokens=1 delims=," %%a in (%source%) do SET "org=%%a"   
for /F "tokens=2 delims=," %%b in (%source%) do SET "month=%%b"  
for /F "tokens=3 delims=," %%c in (%source%) do SET "acct=%%c"
for /F "tokens=4 delims=," %%d in (%source%) do SET "data1=%%d"
for /F "tokens=5 delims=," %%e in (%source%) do SET "data2=%%e"
for /F "tokens=6 delims=," %%f in (%source%) do SET "data3=%%f"
for /F "tokens=7 delims=," %%g in (%source%) do SET "data4=%%g"

set search=3456
set replace=-%data1%


FOR /F "tokens=* delims=," %%i in ("%source%") do
(set newline=%%i
IF /i %acct% EQU %search%
set newline=!newline:%org%,%month%,%acct%,%replace%! 
echo !newline!>>%target%
)  

2)VBS:

@echo objFile.WriteLine strNewText
@echo objFile.CloseConst ForReading = 
@echo Const FileIn = "test.txt"
@echo Const FileOut = "test_adhoc.txt"  
@echo Set objFSO = CreateObject("Scripting.FileSystemObject")
@echo Set objFile = objFSO.OpenTextFile(FileIn, ForReading)
@echo strText = objFile.ReadAll
@echo objFile.Close
@echo strNewText = Replace(strText, "*,*,3456,*,*,*,*", "*,*,3456,-*,-*,-*,-  *")
@echo Set objFile = objFSO.OpenTextFile(FileOut, ForWriting)
@echo objFile.WriteLine strNewText
@echo objFile.Close

Solution

  • The problem with this type of management over large files is that Batch file processing is inherently slow, so any method that may speed up the process is good.

    EDIT: Change the signs of the last four data.

    2ND EDIT: ... when such a data may have decimal point

    @echo off
    setlocal EnableDelayedExpansion
    
    set search=3456
    
    rem Find the number of lines before the target one
    for /F "delims=:" %%a in ('findstr /N "^.*,.*,%search%" source.txt') do set /A lines=%%a-1
    
    rem Reading from the source file
    < source.txt (
    
       rem Copy the lines previous to target one
       for /L %%i in (1,1,%lines%) do set /P "line=" & echo !line!
    
       rem Read and process the target line
       set /P "line="
       for /F "tokens=1-7 delims=," %%a in ("!line!") do (
          set "data1=-%%d" & set "data2=-%%e" & set "data3=-%%f" & set "data4=-%%g"
          echo %%a,%%b,%%c,!data1:--=!,!data2:--=!,!data3:--=!,!data4:--=!
       )
    
       rem Copy the rest of lines
       findstr "^"
    
    ) > output.txt
    
    move /Y output.txt source.txt
    

    In this code the target line is found in one operation via a findstr regex that search for the desired acct no. in the third comma-separated field of the line. The rest of the program is simple enough to be self-explanatory...

    If you have any doubt of any command, you may review its help executing it with /? parameter; for example: findstr /?