Link to home
Start Free TrialLog in
Avatar of MrMay
MrMay

asked on

batch file for dos

I need help writing a batch file and I have no idea on this one.
Can someone please help me out. I tried to find examples on the internet but no luck finding what i need.

This is what I need this batch file to do.
*******************************
Lets say I have a folder called "AAA"
In that folder I have text files... eg. 100a.txt, 101b.txt, 100b.txt, 101a.txt, 100c.txt, 101d.txt"
Each one of these text files has a bunch of lines of numbers. So for example text file 100a.txt has  
001 123 024.33
002 123 024.3
003 123 024 .34
004 123 044.75


and 101a.txt has
001 122 024.33
002 122 024.3
003 122 024 .34
004 122 044.75



1. I need the batch file to go through the AAA folder and delete all text files where there is the letter c or d on the end of it
2. It then takes each remaining text files and it renames it. So it takes 100a.txt and renames it to 100ok.txt,  101b.txt to 101good.txt
3. the batch file then goes into each text file and changes the 5th,6th, and 7th character to something else... so for example... it takes the first line ... 001 123 024.33 and changes it to 001 444 024.33  
... so if line position 5,6,7 = 123 change it to 444
........ if line position 5,6,7 = 122 change it to 333

can this be done... or is it to completed

please & thank you
Avatar of Steve Knight
Steve Knight
Flag of United Kingdom of Great Britain and Northern Ireland image

OK..... lets split that down a bit.

@Echo off
cd /d c:\yourdir\aaa

del ???c.txt 2>NUL
del ???d.txt 2>NUL
rename ???a.txt ???good.txt
rename ???b.txt ???ok.txt

Now this is OK but to have a batch file "change" a text file it is easier to write a new file so we are best off looping through all the "a" files and then writing out a "good" file and then removing the a and b files after I would say something like this.... can't test right now but give it a go for starters on some test files.


@echo off
setlocal enabledelayedexpansion
cd /d c:\whateverdir\aaa

del ???c.txt 2>NUL
del ???d.txt 2>NUL

REM Loop through all xxxa.txt files
for %%a in (???a.txt) do (
  set filename=%%a
  set outname=!filename:~0,3!ok.txt
  echo Creating !outname! from !filename!

  REM Loop through each line of text file. Split at spaces. L = first, M = second, N = rest of line
  (for /f "tokens=1,2* delims= "%%L in ('type "%%a"') do (
    if "%%L"=="122"  echo %%L 444 %%N 
    if "%%L"=="123"  echo %%L 333 %%N
  )) > "!outname!"

  REM Remove the word echo here to remove the file
  echo del "!filename!"
)

REM If that is OK then replica of above section with "good" and "b" in the first for command.
REM Or if it is more than two then would make a subroutine.

Open in new window

Avatar of Bill Prew
Bill Prew

This should do the job nicely.  Save as a BAT file, and adjust the PUSHD to reference the folder where the TXT files are.

@echo off
setlocal EnableDelayedExpansion

pushd C:\ee\EE27831500\AAA

for %%F in (*.txt) do (
  set Name=%%~nF
  if /I "!Name:~-1!" EQU "c" del %%~F
  if /I "!Name:~-1!" EQU "d" del %%~F
  if /I "!Name:~-1!" EQU "a" call :DoEdits "%%~F" "!Name:~0,-1!ok"
  if /I "!Name:~-1!" EQU "b" call :DoEdits "%%~F" "!Name:~0,-1!good"
)

popd
exit /b

:DoEdits
  if exist "%~2.txt" del "%~2.txt"
  for /F "usebackq tokens=1-3" %%A in ("%~1") do (
    set New=%%B
    if "%%B" EQU "123" set New=444
    if "%%B" EQU "122" set New=333
    echo %%A !New! %%C >> "%~2.txt"
  )
  exit /b

Open in new window

~bp
Avatar of MrMay

ASKER

dragon-it.. thank you for your post(code) but it does not work. The only portion that works is the part that deletes the  c and d text files. NOthing else happens.
when I run the batch file in command prompt it comes back with a msg that says
c:\echo off
in was unexpected at this time
Avatar of MrMay

ASKER

billprew.. thank you for your code as well.. but it too does not work. I'm having trouble understanding it. Can u please add some comments to it.  
thank you
Well on first examination in line 16 I left a space out between the " and %%L it should read

(for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (

I will setup a test if this doesn't get answered but too much else going on at the mo. sorry (kids tea and bed times...)

Steve
Hmm, OK 15-17 then:

(for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  echo %%L 444 %%N
    if "%%M"=="123"  echo %%L 333 %%N

Was checking the first parameter, not the second.

Rest looks Ok without actual testing at the mo, like I say.

Steve
My code worked on your sample data files when I ran it here, what problem did you encounter?

~bp
Here is a commented version of the code.

@echo off
setlocal EnableDelayedExpansion

REM Change to the folder where the text files to be processed reside
pushd C:\ee\EE27831500\AAA

REM Process all text files in the folder
for %%F in (*.txt) do (
  REM Get the base file name (no extension) into a variable
  set Name=%%~nF

  REM If the file name ends in "c" or "d" then delete this file
  if /I "!Name:~-1!" EQU "c" del %%~F
  if /I "!Name:~-1!" EQU "d" del %%~F

  REM If the file name ends in "a" or "b" then edit the file and save with new name
  if /I "!Name:~-1!" EQU "a" call :DoEdits "%%~F" "!Name:~0,-1!ok"
  if /I "!Name:~-1!" EQU "b" call :DoEdits "%%~F" "!Name:~0,-1!good"
)

REM Go back to original directory, and exit
popd
exit /b

REM Subroutine to replace a value on each line of a space delimited text file
:DoEdits
  REM If the file exists with the new name, delete it
  if exist "%~2.txt" del "%~2.txt"

  REM Read each line of the file and edit as needed
  for /F "usebackq tokens=1-3" %%A in ("%~1") do (
    REM Get the 2nd token into a variable
    set New=%%B

    REM Replace the 2nd token if it matches
    if "%%B" EQU "123" set New=444
    if "%%B" EQU "122" set New=333

    REM Write the updated line to the output file
    echo %%A !New! %%C >> "%~2.txt"
  )
  exit /b

Open in new window

~bp
Likewise:

Creating 100ok.txt from 100a.txt
del "100a.txt"
Creating 101ok.txt from 101a.txt
del "101a.txt"
Creating 100good.txt from 100b.txt
del "100b.txt"
Creating 101good.txt from 101b.txt
del "101b.txt"

C:\4. WIP\EE\27831500\aaa>type 100a.txt
001 123 024.33
002 123 024.3
003 123 024 .34
004 123 044.75
C:\4. WIP\EE\27831500\aaa>type 101a.txt
001 122 024.33
002 122 024.3
003 122 024 .34
004 122 044.75
C:\4. WIP\EE\27831500\aaa>type 100b.txt
001 123 024.33
002 123 024.3
003 123 024 .34
004 123 044.75
C:\4. WIP\EE\27831500\aaa>type 101b.txt
001 122 024.33
002 122 024.3
003 122 024 .34
004 122 044.75
C:\4. WIP\EE\27831500\aaa>type 100ok.txt
001 333 024.33
002 333 024.3
003 333 024 .34
004 333 044.75

C:\4. WIP\EE\27831500\aaa>type 101ok.txt
001 444 024.33
002 444 024.3
003 444 024 .34
004 444 044.75

C:\4. WIP\EE\27831500\aaa>type 100good.txt
001 333 024.33
002 333 024.3
003 333 024 .34
004 333 044.75

C:\4. WIP\EE\27831500\aaa>type 101good.txt
001 444 024.33
002 444 024.3
003 444 024 .34
004 444 044.75

C:\4. WIP\EE\27831500\aaa>

Open in new window


from what I posted before plus those three changed lines, i.e.:

@echo off
setlocal enabledelayedexpansion
cd /d c:\whateverdir\aaa

del ???c.txt 2>NUL
del ???d.txt 2>NUL

REM Loop through all xxxa.txt files
for %%a in (???a.txt) do (
  set filename=%%a
  set outname=!filename:~0,3!ok.txt
  echo Creating !outname! from !filename!

  REM Loop through each line of text file. Split at spaces. L = first, M = second, N = rest of line
  (for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  echo %%L 444 %%N
    if "%%M"=="123"  echo %%L 333 %%N
  )) > "!outname!"

  REM Remove the word echo here to remove the file
  echo del "!filename!"
)

REM Loop through all xxxb.txt files
for %%a in (???b.txt) do (
  set filename=%%a
  set outname=!filename:~0,3!good.txt
  echo Creating !outname! from !filename!

  REM Loop through each line of text file. Split at spaces. L = first, M = second, N = rest of line
  (for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  echo %%L 444 %%N
    if "%%M"=="123"  echo %%L 333 %%N
  )) > "!outname!"

  REM Remove the word echo here to remove the file
  echo del "!filename!"
)

Open in new window


Are there any special characters or other formatting to those files / filenames that is different -- have you simplified this for us?
Avatar of MrMay

ASKER

Hey billprev... thanks for the comments ... I tried running the batch file again but nothing happens.. no errors, no changes to the files... nothing
If the same for mine, please advise an actual directory listing ... any odd chars, extra files, subdirs with the same names etc.
Likewise perhaps the first dozen lines of a real file attached too.

Steve
Can you post up your sample files please, and mention any changes you made to the script?

~bp
Avatar of MrMay

ASKER

Hey Dragon-it.

Ok... the batch file now changes the text file but it still has a bug when it comes to the data inside the text files.
Please see attached.
As you can see I made changes to the file names (what I need it as).
Notepad #1 is how the file looks before I apply the batch file.. Notepad number #2 is how the file looks after I apply the batch.   As you can see the batch file deletes all the line numbers except for line number 004 and line number 007... I don't want it to delete any lines just change "004" which is character 4,5,6...  
Also the original notepad#1 has the title line. I need to keep that line but also change the 004 that shows up at the end.  

Jpeg#2 is how I want the file to look after the batch file runs.

thansk once again Dragon-it.. u are very helpful with this.
topost.JPG
2.bmp
Right... well my batch assumes it is either 122 or 123 and nothing else makes the ouput.

You could change this bit from:

REM Loop through each line of text file. Split at spaces. L = first, M = second, N = rest of line
  (for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  echo %%L 444 %%N
    if "%%M"=="123"  echo %%L 333 %%N
  )) > "!outname!"

Open in new window


to:

REM Loop through each line of text file. Split at spaces. L = first, M = second, N = rest of line
  (for /f "tokens=1,2* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  (
      echo %%L 444 %%N
    ) else (
       if "%%M"=="123"  (
          echo %%L 333 %%
       ) ELSE (
          echo %%L %%M %%N
       )
   )
  )) > "!outname!"

I think..... if you could give us an actual text file or part of AND the batch you are actually using with your mods then it is easier to see why.
Avatar of MrMay

ASKER

dragon-it... that is working... thank you thank you.

one other question... what sort of code do I need to change the number on the first line.

so it also changes from
Package number 44698 -- fix num: 122
to
Package number 44698 -- fix num: 444

besides this everything else is working for me.
Hmm... will need bit of a fiddle for that - all the info. to start with helps!

Bit of bodge coding here as not time at the mo. to re-write it all

Steve

(for /f "tokens=1-7* delims= " %%L in ('type "%%a"') do (
    if "%%M"=="122"  (
      echo %%L 444 %%N %%O %%P %%Q %%R %%S
    ) else (
       if "%%M"=="123"  (
          echo %%L 333 %%N %%O %%P %%Q %%R %%S
       ) ELSE (
          echo %%L %%M %%N %%O %%P %%Q %%R %%S
       )
   )
 if "%%R"=="122"  (
      echo %%L %%M %%N %%O %%P %%Q 444 %%S
    ) else (
       if "%%R"=="123"  (
          echo %%L %%M %%N %%O %%P %%Q 333 %%S
       ) ELSE (
          echo %%L %%M %%N %%O %%P %%Q %%R %%S
       )
   )


  )) > "!outname!"
Hmm aside from the fact that is messy it will duplicate lines.  Bill - go for it amending yours as you wish, kids to sort out etc.

Would need to do some re-ordering of mine and/or just taking line #1, sorting that out first then appending the rest in a loop.

Would still help to have some actual text files attached!

Steve
I don't understand your file name, you implied in the original question that all file names ended in a, b, c, or d.  But in your example the filename did not fit that?

~bp
A good point bill.  Right I would suggest please like has been mentioned already please post back the actual amended versions of our scripts and a couple of example files as text..

Simplifying a problem is great but then we have to keep modifying, and would have worked different way from start for instance -that e.g. the 'bug'for about not updating the first line we didn't know about!

Steve
Avatar of MrMay

ASKER

Thank you so much so far for your help dragon-it and billprew.
Let me try explaining this one more time and I'll try to be as clear as possible and I'll attach some jpegs and file examples.

Attached is a folder... it holds a bunch of text files.
1. File names that end in 004... I need them renamed them so they end in a.
So for example. File name 44696004.txt will be renamed to 44696a.txt
file names that end in 007 need to end in b
file names that end if 008 need to end in c
file names that end if 009 need to end in d
file names that end in either 005 or 006 need to be deleted

2. Lets take a look at text file 44696004.txt (after the first step it will be renamed to 44696a.txt)
The first line of that text file, Package number 44696 --fixture 004, I need the 004 changed to a
For the rest of the lines I need the 004, which is always found as character 5,6 & 7 changed to an a as well. Please see attached pic1.
and so on... so for example.. text file 44696007.txt (which will be renamed after the first step to 44696b.txt)... so here on the first line I need it to say Fixture b instead of Fixture 007 and I need the 007 (character 5,6, & 7) changed to b.  and so on for files ending in 008 (changed to  c)  and 009 (changed to d).
I hope this makes more sense and is a better explanation.

thank you so much guys.
pic1.JPG
folder.JPG
examples.JPG
Wow.  OK, sorry but I don't have to fathom all that out again, seems completely different to originally.

I would suggest you post some actual text files rather than images of them as then Bill or whoever (or me if I get time) don't have to sit here typing in a load of numbers to test with.
Avatar of MrMay

ASKER

Avatar of MrMay

ASKER

thanks dragon-it... I'm familiar with C# coding but not batch files to this level... so when it comes to this, I'm dead in the water...
Ok, that's probably more like it.  I'm not going to get a chance to look at this till Monday now probably but maybe Bill or someone else can.

Steve
SOLUTION
Avatar of Bill Prew
Bill Prew

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Good stuff, Bill, but why not include the IF of
if /I "!Name:~-3!" EQU "004" call :DoEdits "%%~F" "!Name:~0,-3!a.txt" "004"

Open in new window

into DoEdits itself, so the call is more like
call :DoEdits "%%~F" a.txt 004
...
:DoEdits
set name=%~n1
set dest=%Name:~0,-3%%2
if NOT "%Name:~-3%" EQU "%3" exit /b
...

Open in new window

and we have much less repetition there.
Qlemo,

Interesting, but in this case that would mean 4 calls to the subroutine for each file rather than just the one needed for that file.  That feels like a large performance trade off for less code.

Of course, we could add logic in the DoEdits routine to see what the last 3 digits of the filename are and figure out the rest there, but that ends up being about the same amount of code I expect.

I did think the way I wrote it added a little clarity to the reader about what it was doing, but I fully appreciate that there are always many ways to achieve the same results, and appreciate you sharing your thoughts, always helpful.

~bp
I do not think having to call the subroutine 4 times instead of once is a performance hog, since the check is at the very beginning of the sub and executed almost immediately.

In the end it's a matter of taste. I don't like writing the same (changing) values several times, if I can eliminate the need by simple, straight-forward logic.
Avatar of MrMay

ASKER

Hello billprev...
The code seems to be working good.
The only problem that I still have is the fact that it does not change the value of the first line in each text file. please see attached.
topost.JPG
Avatar of MrMay

ASKER

Hello billprev.... can u please have a second look at the script that you created for me above and please tell me why the text is not being changed on the first line of each text file?

Dragon-it... any suggestions?

I really need this...   please and thank you.
Looks like spaces padded on the end of the line... on test against one of the files:

REM Replace the 3rd token if it matches
if "004                              " EQU "004" set New=a

etc.

If this is right then if we split off token "3" at the next space too then the extra spaces end up in %%D...

PackageNumber 44696--Fixture: 004 a
001 a 036.000 060.000 000.000 000.000 001 000 001 101 031
002 a 036.000 060.000 000.000 000.000 001 000 001 102 032
003 a 027.500 034.500 000.000 000.000 001 000 001 106 032
004 a 051.500 040.500 000.000 000.000 001 000 001 107 031
005 a 063.500 040.500 000.000 000.000 001 000 001 108 032
006 a 051.500 046.500 000.000 000.000 001 000 001 109 031
007 a 072.000 066.000 000.000 000.000 001 000 001 306 032

then try these changes to Bill script... bold bits are changed ones:

  REM Read each line of the file and edit as needed
  for /F "usebackq tokens=1-3*" %%A in ("%~1") do (

    if "!FirstLine!" EQU "Y" (

      REM Get the 3rd token into a variable
      set New=%%C
 
      REM Replace the 3rd token if it matches
      if "%%C" EQU "%~3" set New=%~4

      REM Write the updated line to the output file
      echo %%A %%B !New! %%D>> "%~2"

      REM Flip flag since we handled the first line now
      set FirstLine=N

    ) else (

      REM Get the 2nd token into a variable
      set New=%%B

      REM Replace the 2nd token if it matches
      if "%%B" EQU "%~3" set New=%~4

      REM Write the updated line to the output file
      echo %%A !New! %%C %%D>> "%~2"

    )
Avatar of MrMay

ASKER

Hey dragon-it... My error... there is actually another space on the first line

so instead of
PackageNumber 44696--Fixture: 004

it should be
Package Number 44696--Fixture: 004      (space between package and number)

I'm not sure what needs to be change in the code???
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MrMay

ASKER

it works... a great big THANK YOU to dragon-it and billprev.
thank you, thank you.
Avatar of MrMay

ASKER

worked with me all the way through and provided the solution I was looking for.
Welcome.

~bp
Likewise, interesting one, though knowing the data format in post #1 would have been easier!

Steve