how to encrypt a text file using batch? - batch-file

How can i encrypt the content in a text file using batch? and how can i decrypt it?
i have tried setting each letter to a number but i do not know how to split the string into each letter and do that.
I watched a video on youtube that help turn letters into numbers but it did not do it with a file.
this is the code he provides in the video.
#echo off
setlocal enableDelayedExpansion
set /p code=Text:
set chars=0123456789abcdefghijklmnopqrstuvwxyz
for /L %%N in (10 1 36) do (
for /F %%C in ("!chars:~%%N,1!") do (
set "code=!code:%%C=%%N!"
)
)
echo !code!
pause
Please help Thank you

#ECHO OFF
SET abet=abcdefghijklmnopqrstuvwxyz!##-/\ .0123456789
SET cipher1=8p#j4 9z\6w.ae#0u2r5o!xk-cf1b3g7hmqil/sntdvy
(
FOR /f "delims=" %%a IN (q20794050.txt) DO (
SET line=%%a
CALL :encipher
)
)>q20794050.txt.1
(
FOR /f "delims=" %%a IN (q20794050.txt.1) DO (
SET line=%%a
CALL :decipher
)
)>q20794050.txt.2
GOTO :EOF
:decipher
SET morf=%abet%
SET from=%cipher1%
GOTO trans
:encipher
SET from=%abet%
SET morf=%cipher1%
:trans
SET "enil="
:transl
SET $1=%from%
SET $2=%morf%
:transc
IF /i "%line:~0,1%"=="%$1:~0,1%" SET enil=%enil%%$2:~0,1%&GOTO transnc
SET $1=%$1:~1%
SET $2=%$2:~1%
IF DEFINED $2 GOTO transc
:: No translation - keep
SET enil=%enil%%line:~0,1%
:transnc
SET line=%line:~1%
IF DEFINED line GOTO transl
ECHO %enil%
GOTO :eof
Here's a way to do it using a simple Cæsar (substitution) code.
abet can be set (possibly from a file) to the set of characters that you want to encode. Similarly, cipher1 can be set to the transled set - just make sure that each character in abet also appears in cipher1.
Any character that appears in the input text but not in abet will not be translated.
I used q20794050.txt:
The quick brown fox [jumps] {over} the lazy dog 9876543210.
9876543210 The quick brown fox !##-/\ jumps over the lazy dog.f
Which was encoded to q20794050.txt.1 :
5z4huo\#whp2#xeh #kh[6oa0r]h{#!42}h5z4h.8c-hj#9hyvdtns/liqm
yvdtns/liqh5z4huo\#whp2#xeh #khf1b3g7h6oa0rh#!42h5z4h.8c-hj#9m
(Note that there is a Space at the end of that last line...)
And was successfully disencrypted to q20794050.txt.2
Note: the above won't handle certain problem characters like %&|><
I've only used lower-case so any upper-case would be translated to lower-case by the process. If you remove the /i from the IF statement, then case will be preserved, but you'd have to add the upper-case letters to abet and cipher1 else the encrypted file will contain the upper-case characters verbatim.
Note that
(for...do (...))>somefilename
will create a new file somefilename containing any data ECHOed - even if the ECHO occurs in a subroutine.

#echo off
setlocal enableDelayedExpansion
for /f "tokens=* delims= " %%h in ('type %1') do (
set text=%%h
)
set chars=0123456789abcdefghijklmnopqrstuvwxyz
for /L %%N in (10 1 36) do (
for /F %%C in ("!chars:~%%N,1!") do (
set "text=!text:%%C=-%%N!"
)
)
echo !text! > %userprofile%\Desktop\encrypted.txt
pause
(using a different .bat file)
#echo off
setlocal enableDelayedExpansion
for /f "tokens=* delims= " %%h in ('type %1') do (
set text=%%h
)
set chars=0123456789abcdefghijklmnopqrstuvwxyz
for /L %%N in (10 1 36) do (
for /F %%C in ("!chars:~%%N,1!") do (
set "text=!text:%%N=%%C!"
)
)
for /f %%K in ("!text!") do (
set "text=!text:-=!"
)
echo !text! > %userprofile%\Desktop\decrypted.txt
pause

Related

Removing carriage returns from a text file using a batch file based on a value

I have a text file that I would like to edit and therefore would like to remove the last line. I have the following code for this:
for /f "delims=" %%a in (input.txt) do (
echo/|set /p ="%%a%"
)>>output.txt
input:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Now I would like to edit the data in groups for example by the first value, so that I have the following output:
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
If I replace the FOR /F "delims=" %%a in (input.txt) do … loop with an equivalent FOR %%a in … loop:
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
set "_gruppeName="
(
for %%a in (
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
"GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;"
) do (
for /f "tokens=1 delims=;" %%A in ("%%~a") do (
if /I NOT "%%~A"=="!_gruppeName!" (
if defined _gruppeName echo(
set "_gruppeName=%%~A"
)
)
echo/|set /p ="%%~a"
)
echo(
)>>output.txt
REM debugging output follows
type output.txt
Output:
1st run: 2>NUL del output.txt & D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Next run: D:\bat\CR\61816520.bat
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEA;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEB;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;GRUPPEC;123;12345;sdfdsfds;sdfdsfsdfs;sdfsdfafsf;
Your question is not clear
based on ... the first value (GRUPPEA)
is it SORTed? or just write duplicates on the same line?
#echo off
SETLOCAL EnableExtensions EnableDelayedExpansion
::VARIABLES
set "in=input.txt" IN file
set "out=output.txt" OUT file
set/a"#lines=0"
set "gruppe="
set "prevContent="
::Count lines
FOR /F %%L in ('
"findstr /N "^^" "%in%" %= do not skip empty lines =%"
') do set/a"#lines+=1" %= Get the # of lines =%
::Read IN via SET /P #LINES number of times
::Bangs (!) will be lost
<"%in%" >"%out%" (FOR /L %%# in (1 1 %#lines%) do (
set "data=" ::clear DATA
set/p"data=" ::read from IN
FOR /F tokens^=1^ delims^=^;^ eol^= %%T in ("!data!") do set "gruppe=%%T"
if NOT "!prevContent!" == "!gruppe!" (
set "prevContent=!gruppe!"
echo(
)
<nul set/p"=!data!" ::does not work with leading space, tabs, or equal signs
)) %= read file by lines via SET /P =%
exit /b
The script counts the number of lines using FINDSTR /N and a FOR /F loop to count the # of lines, which is required to execute SET /P that many times.
Tips:
Use ECHO( instead of the problematic ECHO.
Using a pipe | is very slow, as described by #jeb here. Use <nul instead

Cut off block based on certain strings in a file

I have a task to cut off the block starting from certain string in the middle of a file and then to save this upper part of the file into a new file.
;---- Some text A
aaaaaaa1111
……..
aaaaaaa2222
;-----Some text B
bbbbbbbbb1111
…………..
bbbbbbbbb2222
Now I am looking for a batch file to cut off the part starting from:
;-----Some text B
So after cut, the new file looks like:
;---- Some text A
aaaaaaa1111
……..
aaaaaaa2222
All the part starting from:
;-----Some text B
bbbbbbbbb1111
…………..
bbbbbbbbb2222
has been cut off.
I tried to use the Function from DOStip then call that function as below:
#ECHO OFF
REM.-- Prepare the Command Processor
SETLOCAL ENABLEEXTENSIONS
SETLOCAL ENABLEDELAYEDEXPANSION
echo.Extracting hello world block into "Load_SDK.M83" file
call:extractFromFile ";---- Some text A" ";---- Some text B">"Load_SDK.M83"
:extractFromFile - extract lines from a file between begin and end mark
:: - %~1: begin mark, use '...$' mark to allow variable substitution
:: - %~2: optional end mark, default is end of file
:: - %~3: optional source file, default is THIS file
SETLOCAL
set bmk=;---- Some text A
set emk=;---- Some text B
set src=C:\Files\Load_all.M83
set /a b=-1
set /a e=-1
if "%src%"=="" set src=%~f0& ::- if no source file then assume THIS file
for /f "tokens=1,* delims=:" %%a in ('"findstr /n /b /c:"%bmk%" "%~f0""') do (
set b=%%a
set bmk=%%b
)
if /i %b%==-1 echo.ERROR: begin mark '%bmk%' not found in '%src%'&GOTO:EOF
if "%emk%"=="" (set /a e=2000000000) ELSE (
for /f "delims=:" %%a in ('"findstr /n /b /c:"%emk%" "%~f0""') do (
if /i %b% LSS %%a if /i !e!==-1 set e=%%a& rem -- find only the first one after b
)
)
if /i %e%==-1 echo.ERROR: end mark '%emk%' missing in '%src%'&GOTO:EOF
if /i %b% GEQ %e% echo.ERROR: end mark '%emk%' detected before begin mark '%bmk%' in '%src%'&GOTO:EOF
for /f "delims=: tokens=1,*" %%a in ('"findstr /v /n /b /c:"#$*ReturnAll*$#" "%src%""') do (
if /i %b% LSS %%a if /i %%a LSS %e% (
if "%bmk:~-1%"=="$" (
rem --sustitution variables within %%b
call echo.%%b
) ELSE (
rem --no variable substitution
echo.%%b
)
)
)
GOTO:EOF
Based on my comment, a one line single For loop with an If and a GoTo seems to perform the task as shown in your question:
#(For /F UseBackQDelims^=^ EOL^= %%A In ("source.txt") Do #If /I Not "%%A"==";-----Some text B" (Set /P "=%%A"<Nul&Echo=) Else GoTo :EOF)>"result.txt"

count an exact character in one line - cmd

I would like write a batch file to count the number of occurrences of a specific character in each line of a text file.
For example, the count of \ in the string "aa\bb\cc\dd\" would be 4.
The find and the findstr show only the number of lines which is contains the exact character.
You might try the following script, providing the input string as (quoted) command line argument:
set "STRING=%~1$"
set STRING="%STRING:\=" "%"
set /A "COUNT=-1"
for %%E in (%STRING%) do set /A "COUNT+=1"
echo Count of `\`: %COUNT%
This replaces every character to be counted by " + SPACE + " and encloses the entire string in between "", so the input string aa\bb\cc\dd\ becomes "aa" "bb" "cc" "dd" "". The resulting string is fed into a for loop that recognises individual items to iterate through -- five in this case. The counter variable COUNT is initialised with a value of -1, so the result is not the number of iterated items but the separators, namely the \ characters present in the original string.
This approach fails if the string contains ? or * characters. It would also fail in case the character to count is one of the following: ", %, =, *, ~.
#echo off
setlocal
set "string=aa\bb\cc\dd\"
set "count=-1"
for %%a in ("%string:\=" "%") do set /A count+=1
echo %count%
This method works correctly as long as the string don't include wild-card characters: *?; if this is required, I would use the same npocmaka's method, but written in a simpler way:
#echo off
setlocal EnableDelayedExpansion
set "string=aa\bb\cc\dd\"
set "str=A%string%Z"
set "count=-1"
for /F "delims=" %%a in (^"!str:\^=^"^
% Do NOT remove this line %
^"!^") do (
set /A count+=1
)
echo %count%
While slow, you can try with this
#echo off
setlocal enableextensions disabledelayedexpansion
set "inputFile=input.txt"
set "searchChar=\"
for /f "delims=" %%a in ('
findstr /n "^" "%inputFile%"
') do for /f "delims=:" %%b in ("%%~a") do (
set "line=%%a"
for /f %%c in ('
cmd /u /v /e /q /c"(echo(!line:*:=!)"^|find /c "%searchChar%"
') do echo Line %%b has %%c characters
)
The input file is readed using findstr /n to get all the lines in the file with a number prefix (both for output "decoration" and to ensure all the lines in the file are processed). Each line is processed inside a pipe, from cmd to find. The cmd instance is started with unicode output (/u) so when the readed line is echoed, the output will be a two bytes sequence for each input character, one of them a 0x0 ASCII character. The find command sees the 0 as a line terminator, so we get each character in the input line as one separated line. Now, the find command counts in how many lines the searched character happens.
#ECHO OFF
SETLOCAL
SET "String=a\b\c\\\\d"
CALL :count "%string%" \
ECHO %tally%
GOTO :EOF
:count
SETLOCAL enabledelayedexpansion
SET /a tally=0
SET "$2=%~1"
:cloop
SET "$1=%$2%"
SET "$2=!$1:*%2=!"
IF "%$1%" neq "%$2%" SET /a tally+=1&GOTO cloop
endlocal&SET tally=%tally%
GOTO :eof
Here's a way to count particular characters in a string. It won't work for the usual suspects.
here's one way:
#echo off
:checkCountOf string countOf [rtnrVar]
:: checks count of a substring in a string
setlocal EnableDelayedExpansion
set "string=aa"
set "string=%~1"
set "checkCountOf=%~2"
if "%~1" equ "" (
if "%~3" neq "" (
endlocal & (
echo 0
set "%~3=0"
exit /b 0
)
) else (
endlocal & (
echo 0
exit /b 0
)
)
)
if "!checkCountOf!" equ "$" (
set "string=#%string%#"
set "string=!string:%checkCountOf%%checkCountOf%=#%checkCountOf%#%checkCountOf%#!"
) else (
set "string=$%string%$"
set "string=!string:%checkCountOf%%checkCountOf%=$%checkCountOf%$%checkCountOf%$!"
)
set LF=^
rem ** Two empty lines are required
set /a counter=0
for %%L in ("!LF!") DO (
for /f "delims=" %%R in ("!checkCountOf!") do (
set "var=!string:%%~R%%~R=%%~L!"
set "var=!var:%%~R=%%~L!"
for /f "tokens=* delims=" %%# in ("!var!") do (
set /a counter=counter+1
)
)
)
if !counter! gtr 0 (
set /a counter=counter-1
)
if "%~3" neq "" (
endlocal & (
echo %counter%
set "%~3=%counter%"
)
) else (
endlocal & (
echo %counter%
)
)
you can call it like:
call ::checkCountOf "/aa/b/c/" "/" slashes
echo %slashes%
exit /b %errorlevel%
wont work with some special characters (",~ and !)
You can also use replacement and the :strlen function
Not tested extensively but works with your example.
#ECHO OFF
SETLOCAL disabledelayedexpansion
SET "String=\a\b\c\\\\d\\"
set "previous=%string%"
set /a count=0
:loop
set "newstg=%previous:*\=%"
IF NOT "%previous%"=="%newstg%" (
set /a count+=1
set "previous=%newstg%"
IF DEFINED previous goto loop
)
echo %count%
pause
GOTO :eof
Here is one more option. I don't think this is bullet proof with poison characters.
#ECHO OFF
SETLOCAL disabledelayedexpansion
SET "String=\\a\b\c\\\\d\\"
set i=0
set "x=%string%"
set "x=%x:\=" & set /A i+=1 & set "x=%"
echo %i%
pause

Splitting txt using batch containing "=" on each line

I'm splitting the file every 6000 lines with the script below but I'm having a problem with it....
Every line of my txt file has the character '=' so when the batch is treating the file, where I have the '=' the line stops and goes to the next one (I don't have the end of each line, anything that follows the = is deleted).
FOR %%X IN (*.TXT) do (
setlocal ENABLEDELAYEDEXPANSION
SET BFN=%%X
SET LPF=6000
SET SFN=%%X_6000_
)
REM ==============================
SET SFX=%BFN:~-3%
SET /A LineNum=0
SET /A FileNum=1
For /F "delims==" %%l in (%BFN%) Do (
SET /A LineNum+=1
echo %%l >> %SFN%!FileNum!.%SFX%
if !LineNum! EQU !LPF! (
SET /A LineNum=0
SET /A FileNum+=1
)
)
endlocal
Can Someone help me out?
Sample of file:
A88A0A1891BAA9=B088A00000003800001==00000038000
A88A0A1B13A0BB=B088A00000089000002==00000890000
A88A0A1A13B830=B088A000000B3800003==00000B38000
A88A0A00331831=B088A00000010A00004==0000010A000
A88A0A10B31B39=B088A00000090A00005==0000090A000
A88A0A19A3AA89=B088A00000089800006==00000898000
A88A0A19AA0318=B088A000000A0100007==00000A01000
A88A0A08911913=B088A00000008800008==00000088000
A88A0A1089A139=B088A00000098300009==00000983000
A88A0A1BB8BBA8=B088A000000AA100010==00000AA1000
A88A0A0A8B9199=B088A00000098100011==00000981000
A88A0A19AA8A9B=B088A00000088900012==00000889000
A88A0A0B380A13=B088A00000099A00013==0000099A000
A88A0A13899A18=B088A00000088A00014==0000088A000
A88A0A1A188910=B088A0000008A800015==000008A8000
A88A0A10930AA0=B088A0000009B900016==000009B9000
A88A0A09338A88=B088A000000A0A00017==00000A0A000
A88A0A11A98930=B088A000000AAB00018==00000AAB000
Setting the LPF (lines Per File) to 6, here is the result (first of 3 files):
A88A0A1891BAA9
A88A0A1B13A0BB
A88A0A1A13B830
A88A0A00331831
A88A0A10B31B39
A88A0A19A3AA89
Thanks!
Remove the second = in the delims :
For /F "delims=" %%l in (%BFN%) Do (
delims== means the command tries to split each line with =
What you need is
For /F "tokens=*" %%l in (%BFN%) Do
This means "give me the whole line without splitting it into tokens"
Also in your code above the nesting of the do ( ) blocks seems wrong.
It looks like the first for loop simply sets environment variables and does nothing else. Did you actually run this code?
It should be
#echo off
FOR %%X IN (*.TXT) do (
setlocal ENABLEDELAYEDEXPANSION
SET BFN=%%X
SET LPF=6000
SET SFN=%%X_6000_
REM ==============================
SET SFX=%BFN:~-3%
SET /A LineNum=0
SET /A FileNum=1
For /F "tokens=*" %%l in (%BFN%) Do
SET /A LineNum+=1
echo %%l >> %SFN%!FileNum!.%SFX%
if !LineNum! EQU !LPF! (
SET /A LineNum=0
SET /A FileNum+=1
)
)
endlocal
)

Coping with for loop batch file issues when splitting a text file

Good Afternoon!
Long time reader, first time poster! I have been having a lovely time trying to modify a working batch file to account for variability. The situation is that I have a variable-size text document that normally would be able to be split into sections of 252 lines. The code below worked like a champ:
#echo off & setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: batchsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set /A Split=%Full%/252
for /L %%G in (1,1,%Split%) do type nul > "%name%_%%G%.new"
set X=1
set N=1
set Q=1
set limit = 252
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
set /A Q+=1
echo.%%k>> "%name%_!X!%.new"
if !Q! gtr 252 (
set /A X+=1
set /A Q=1
) else if !N! gtr Full (goto theend
)
)
:theend
echo split into %split% files with 252 lines each
rem pause
However, there were some changes to the formatting of the text, and now instead of four pages of 63 lines per split file, it can be completely variable. The only constant is this final line, which precedes the remaining space for a 63 line page:
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
Note that there is a single space in front of it, as well as multiple spaces, a colon, and underscore characters. Being the meathead that I am, I thought I could insert an if-then statement into the for loop to trigger the batch to split to the next page. However, I could be further from that right now. This is the code I have been smashing my head with:
rem #echo off & setlocal EnableDelayedExpansion
setlocal EnableDelayedExpansion
set param=%*
if not defined param (
echo.
echo. Usage: textsplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
goto :EOF
)
for %%j in ("%param%") do (
set Name=%%~dpnj
set ext=%%~xj
)
for /F %%j in ('type "%param%" ^| find /V /C ""') do set Full=%%j
set stopvar= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
set Split=1
echo %stopvar%
set X=1
type nul > "%name%_!X!%.new"
set N=1
set Q=1
set S=0
set L=63
for /F "tokens=1* delims=]" %%j in ('type "%param%" ^| find /V /N ""') do (
set /A N+=1
echo %N%
set /A Q+=1
echo %Q%
echo.%%k>> "%name%_!X!%.new"
if ["%%k%" == "!stopvar!"] (
set /A S+=1
)
if !Q! gtr !L! (
if !S! == 1 (
set /A X+=1
set /A Q=1
type nul > "%name%_!X!%.new"
set /A Split+=1
set S=0
)
else set /A L+=63
else if !N! gtr Full goto theend
)
:theend
echo Split into %split% files!
pause
The premise is that every 63 lines, the stop variable (S) is checked. If it is off (0) then the batch will continue to write for another 63 lines (one page). If the stopvar matches the line that is being read by the for loop, S becomes 1. When the program checks again, it will create a new file and begin writing to that new file. Right now, based on turning off #echo off the hangup is at the for loop. See below:
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rrtextsplit texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>rem #echo off & setlocal Enabl
eDelayedExpansion
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>setlocal EnableDelayedExpansio
n
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not defined param (
echo.
echo. Usage: rrtextsplit [device:][pathname]filename
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set param=texttest.txt
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>if not exist "texttest.txt" (
echo.
echo. File "texttest.txt" not found
goto :EOF
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for %j in ("texttest.txt") do
(
set Name=%~dpnj
set ext=%~xj
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>(
set Name=C:\Users\theangryasiancp\Desktop\TEXT_Split_Test\texttest
set ext=.txt
)
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>for /F %j in ('type "texttest.
txt" | find /V /C ""') do set Full=%j
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Full=567
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set stopvar= ON THIS FORM IS C
OMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Split=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>echo ON THIS FORM IS COMPLETE
AND CORRECT AS NOTED:___________________
ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set X=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>type nul 1>"C:\Users\theangry
asiancp\Desktop\RRRR_Split_Test\texttest_!X!.new"
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set N=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set Q=1
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set S=0
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>set L=63
C:\Users\theangryasiancp\Desktop\TEXT_Split_Test>
What are your thoughts? Where am I going wrong with the batch? I wish I could use something different, but alas I cannot, for internal company reasons. Thanks for your help!
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "name=q23396663"
SET "ext=.txt"
SET /a pagelength=10
SET "targetstring= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
SET /a filenum=0
SET /a linecount=pagelength + 1
FOR /f "tokens=1*delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
IF !linecount! GEQ %pagelength% (
SET /a linecount=0
SET /a filenum+=1
)
>>U:\%name%_!filenum!.new ECHO(%%b
IF "%%b"=="%targetstring%" SET /a linecount=pagelength
SET /a linecount+=1
)
GOTO :EOF
For testing purposes, I set up a file q23396663.txt containing your trigger data. I've left the destination directory as U:\ which suits me, and the pagelength at 10 which makes my testing easier.
#echo off
setlocal EnableDelayedExpansion
REM ------------------THIS SECTION SPECIFIES THE FILE-------------------------
set param=%*
if not defined param (
echo.
echo. Usage: filesplit [device:][pathname]filename
goto :EOF
)
set param=%param:"=%
if not exist "%param%" (
echo.
echo. File "%param%" not found
GOTO :EOF
)
for %%j in ("%param%") do (
set name=%%~dpnj
set ext=%%~xj
)
ECHO SPLITTING %name%.%ext% .................
REM ----------------THIS SECTION SETS THE VARIABLES---------------------------
set "trigger= ON THIS FORM IS COMPLETE AND CORRECT AS NOTED:___________________"
set /a pagelength=63
set /a filenum=0
set split=1
set /a linecount=pagelength
set stopvar=0
REM ------------------THIS SECTION IS THE FOR LOOP----------------------------
FOR /f "skip=2 tokens=1* delims=]" %%a IN (
'find /v /n "" "%name%%ext%"') DO (
SET /a linecount-=1
IF !linecount! LEQ 0 (
IF !stopvar! EQU 1 (
SET /a "linecount=pagelength"
SET /a filenum+=1
SET /a split+=1
SET /a stopvar-=1
) else set /a "linecount=pagelength"
)
echo.%%b>> "%name%_!filenum!.new"
IF "%%b"=="%trigger%" (
set /a "stopvar+=1"
REM THIS TRIGGERS TO CHANGE OUTPUT
set /a linecount+=1
REM THIS WILL ADJUST THE OUTPUT EOF
)
)
REM ----------------THIS SECTION ENDS THE FOR LOOP----------------------------
ECHO Split into %split% files!
ping 1.1.1.1 -n 1 -w 2500 > nul
REM THIS PAUSES THE BATCH FOR A SEC
As I posted in the comment above, this is just a variation of the first answer that accounts for blank spaces if they are needed to keep the output files from having unnecessary whitespace on top. This is especially helpful when a print manager is just spitting out whitespace until the end of the page before starting the next part instead of going straight to the next portion.

Resources