Reputation: 7792
I have a folder full of text files that I need to split based on the (optional) presence of a delimiter. I found an answer for how to actually split the file here: Split text file into 2 files by separator
@echo off&setlocal
set "file=_frmCore.frm"
for /f "delims=[]" %%i in ('^<"%file%" find /n "SearchTermHere"') do set "split=%%i"
(for /f "tokens=1*delims=[]" %%i in ('^<"%file%" find /n /v ""') do if %%i lss %split% echo(%%j)>"%file%.new1"
<"%file%">"%file%.new2" more +%split%
type "%file%.new?"
Works great for what it is, but I need a few refinements and not sure where to start. Looking for:
(apologies... I've tried deciphering this code and finding out what does what and trying to go from there, but this stuff is not my cup of tea and a strong push in the right direction would be wonderful)
Upvotes: 0
Views: 2235
Reputation: 7792
Sorry, I was unable to use either of the proposed solutions. However they did help - I spent the last two days learning about the (odd) syntaxes and operations involved in batch files and came up with the following. It doesn't do quite everything that I was looking for (and I altered the program that outputs the files a bit for further support), but it does get the job done:
@ECHO off
setlocal EnableDelayedExpansion
:: change the working directory to match the input
cd /D %~d1
cd %~p1\
:: loop all .frm files and find the CodeBehindForm string
for %%F in (*.frm) do (
for /F "delims=[]" %%a in ('^<%%F find /n "CodeBehindForm"') do (
if %%a gtr 0 (
for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i gtr %%a echo(%%j)>>"%%~nF.vb"
for /F "tokens=1*delims=[]" %%i in ('^<"%%F" find /n /v ""') do if %%i lss %%a echo(%%j)>>"%%~nF.fwm"
:: if the codebehind was found and parsed out, there's a .fwm and .vb file
:: remove the original
if exist %%~nF.vb del %%F
)
)
:: change the .fwm extensions back to their original .frm extensions
ren *.fwm *.frm
I'm sure it's not "correct" in many ways, but for now it gets the job done.
Thanks for the help.
Upvotes: 0
Reputation: 67216
Excuse me. Although your description is extensive, it is also confusing. The Batch file below:
.
@echo off
setlocal EnableDelayedExpansion
set "find=SearchTermHere"
set "prevLine=PreviousLine"
rem Process the folder given in parameter
cd %1
rem Process all files in folder
for /F "delims=" %%F in ('dir /A-D /B') do (
rem Get the line number of the search line - 1
set "numLines="
for /F "delims=:" %%a in ('findstr /N "^%find%$" "%%F"') do set /A "numLines=%%a-1"
if defined numLines (
rem Open a code block to read-input-file/create-output-file
< "%%F" (
rem Copy numLines-1 lines
for /L %%i in (1,1,%numLines%) do (
set "line="
set /P "line="
echo(!line!
)
rem If the line before search is prevLine
if "!line!" equ "%prevLine%" (
rem Copy just the search line to original file
set /P "line="
echo !line!
rem and copy the rest of lines to another file
findstr "^" > "%%~nF-PART2%%~xF"
)
) > "%%F.tmp"
if exist "%%~nF-PART2%%~xF" (
rem Replace original file with created output file (first part)
move /Y "%%F.tmp" "%%F" > NUL
) else (
rem Remove the output file
del "%%F.tmp"
)
)
)
For a further explanation of this method, see this post.
Upvotes: 1
Reputation: 30113
@ECHO OFF >NUL
SETLOCAL enableextensions
rem enabledelayedexpansion
set "_files=*.frm"
set "_sfind=SearchTermHere"
if not "%~1"=="" if exist "%~1\" (
pushd "%~1"
set "_popd=popd"
) else ( set "_popd=" )
for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
type NUL > "%%G.new1"
type NUL > "%%G.new2"
for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
for /f "tokens=1* delims=:" %%I in ('findstr /n "^" "%%G"') do (
if %%I lss %%i (
>> "%%G.new1" echo(%%J
)
if %%I gtr %%i (
>> "%%G.new2" echo(%%J
)
)
)
rem remove `ECHO` from next line no sooner than debugged!
ECHO move /Y "%%G.new1" "%%G"
type "%%G.new?"
)
%_popd%
Changes made in your code:
for /F "delims=" %%G
loop against all files matching your criteria: findstr /m "^%_sfind%$" %_files%
.^
=beginning of line and $
=end of line in findstr /m "^%_sfind%$" %_files%
; used findstr
command rather than find
.move /Y "%%G.new1" "%%G"
workaround. Operational move
command is ECHO
ed here merely for debugging purposes. Remove ECHO
from that line no sooner than debugged!call "batch path\31749577.bat" "folder path"
%~1
test: if a parameter is supplied to the batch and represents a folder, (more in Command Line arguments (Parameters)) andpushd
- popd
pair: PUSHD
changes the current directory/folder and store the previous folder/path for use by the POPD
command. The tricky <"%%G">"%%G.new2" more +%%i
command substituted with less effective but clear to understand if %%I gtr %%i ( ...
inside the %%I
loop. However, next code snippet (entire %%G
loop) will work as well:
for /F "delims=" %%G in ('findstr /m "^%_sfind%$" %_files%') do (
for /f "delims=:" %%i in ('findstr /n "^%_sfind%$" "%%G"') do (
>"%%G.new1" (for /f "tokens=1* delims=:" %%I in ('
findstr /n "^" "%%G"') do if %%I lss %%i echo(%%J)
<"%%G">"%%G.new2" more +%%i
)
rem remove `ECHO` from next line no sooner than debugged!
ECHO move /Y "%%G.new1" "%%G"
type "%%G.new?"
)
Upvotes: 1