0

I am working on an HR data project and after much research and even more trial and error, I have adapted the following Batch File (Windows 8.1 environment) that successfully pulls an employee’s start date from a messy text file - with many thanks to user dbenham for that prior solution (again which I adapted as follows):

@echo off
setlocal disableDelayedExpansion
set "cnt=1"
>OUTPUT.txt (
  for /f "skip=219 tokens=24,25,26 delims= " %%B in (MVANHOUTEN.txt) do (
    echo(%%B %%C %%D
    set /a "1/(cnt-=1)" 2>nul || goto :break
  )
)
:break

Where MVANHOUTEN.txt is the input file

OUTPUT.txt file contains only: January 21, 1991

I have a limited understanding of the intricacies of batch file programming, and despite the genius of dbenham's code which I have confirmed works 100% with my changes above, I do not know enough to alter this without breaking it. I need this batch file to do three more things but I cannot seem to make it work without destroying the functionality of the above code. Specifically, I need to:

  1. I need to add the original text filename to the contents of the output file after the data extract. That is, I need my output file to contain: MVANHOUTEN January 21, 1991
  2. Instead of OUTPUT.txt, I need my output file to be named with the same filename as the input file – that is, MVANHOUTEN.txt. If this is not possible or too unweildy, adding to the original filename would be an okay alternative – e.g. MVANHOUTEN-Processed.txt)
  3. I need a do loop as I have a directory of nearly 200,000 current and former employees and I need to batch perform the above operations for each and every file - so logically in place of "(MVANHOUTEN.TXT)" in the above, I need to find a way to loop through many *.txt files in the same directory. The results would be separate files MVANHOUTEN.txt, CMONTYBURNS.txt, DISCOSTU.txt, etc. etc. (or MVANHOUTEN-Processed.txt, CMONTYBURNS-Processed.txt, DISCOSTU-Processed.txt, etc.).

Can anybody please help me enhance my batch file above to accomplish the above without breaking the original scrub I successfully adapted from dbenham? Many thanks in advance!

B. Boomer
  • 3
  • 4
  • 1
    What is the `set /a` statement for? – SomethingDark Jun 09 '17 at 19:27
  • You will need nested FOR commands. The outer being a standard FOR command to iterate all the file names and the inner FOR command will be your current FOR /F. – Squashman Jun 09 '17 at 19:39
  • I'd find it odd or unfortunate if the only way to retrieve the information you need from the file is to skip the first 219 lines and then split out tokens 24-26. As you can imagine it would be a difficult proposition for us to provide an adequate alternative without also knowing the layout and structure of the input file. Because of this we would need to view the entire file and be assured that all of the other files are similar enough to use that one as a basis. – Compo Jun 10 '17 at 12:20
  • @compo-Why would this be odd? I appreciate your curiosity but it does not in any way relate to the actual questions being asked. The code presented works 100%. The question is not why it works or even the "unfortunate way" the data has to be parsed (that part is solved, and HR data is proprietary). This question is HOW to 1)append the filename to each result, 2)name the result appropriately, and 3)process multiple instances in a for loop. – B. Boomer Jun 12 '17 at 00:26

1 Answers1

0

untested, as I don't have your datafiles:

@echo off
setlocal disableDelayedExpansion

for /f "delims=" %%a in ('dir /b *.txt') do (
  call :process %%a
)

:process
set "cnt=1"
>"%~n1-Processed.txt" (
  for /f "skip=219 tokens=24,25,26 delims= " %%B in (%~nx1) do (
    echo( %~n1 %%B %%C %%D
    set /a "1/(cnt-=1)" 2>nul || goto :eof
  )
)
Stephan
  • 53,940
  • 10
  • 58
  • 91
  • Excellent and spot on, Stephan! This works beautifully and is exactly the solution I sought (I only had to remove the leading " before the %~n1-Processed.txt). I very much appreciate your answer and will mark as such. Just so I can learn, how might I change this code if I wanted to overwrite the original filename (instead of appending -Processed to it)? Many thanks again, Sir! – B. Boomer Jun 12 '17 at 18:07
  • overwriting won't work, because you still want to read from the same file (the file will get overwritten *before* you could read the data). Use a rename when reading is finished: `move /y "%~n1-Processed.txt" "%~nx1"`. Put it before the `goto :eof`: `... || ( move /y "%~n1-Processed.txt" "%~nx1" & goto :eof ) – Stephan Jun 12 '17 at 19:18