How to get required output from a bat file to csv file? - batch-file

I had to write a .Bat file in MS-Command prompt to extract 2 specific strings "Username" and "last login time" from a folder having say a 100 log files and each of these log file has these 2 things. The output must be printed to a csv file report to be saved somewhere.
echo Processing user's last login time. Please wait...
S:
cd log_files
for %G IN (*.txt) do (findstr /i "Username: Log-In" "%G" >> S:\Sourav\GIS_Login_Time.txt)
echo Execution Complete.
echo Output file created in C:\data folder.
pause
The output file (in txt format) is like below :
*** OS Username: ADIELA
*** GIS Username: adiela ( Laura Adie - Horizons, Bullion )
*** Log-In Time: 21/07/2014 06:37:20
*** OS Username: allanj1
*** GIS Username: allanj ( Jim Allan - Shared access Lomond House )
*** Log-In Time: 17/12/2014 11:44:22
...
Could you please advise how to modify the output (which goes to a text file now) to go into a csv file? The output file must have 3 columns. 1)OS Username 2) GIS USername 3) Log-In time.
I would greatly appreciate if I could get some valuable suggestions for this.
Thank you in advance :)

Another perfect problem for my JREPL.BAT utility - a hybrid JScript/batch script that performs a regular expression search and replace on text. JREPL.BAT is pure script that runs natively on any Windows machine from XP onward.
Assuming every file has all three entries in the same order (though not necessarily consecutively), then this one liner will create "output.csv". Note that I used line continuation just so the code is easier to read.
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)$[\s\S]*?Log-In Time:\s*(.*?)$" ^
"'\x22'+$1+'\x22,\x22'+$2+'\x22,\x22'+$3+'\x22'" ^
/m /jmatch /o output.csv
-- OUTPUT using your example text --
"ADIELA","adiela ( Laura Adie - Horizons, Bullion )","21/07/2014 06:37:20"
"allanj1","allanj ( Jim Allan - Shared access Lomond House )","17/12/2014 11:44:22"
If you truly want just the GPS username, without the parenthesized info, then you don't need quotes because your data no longer contains commas:
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
"$1+','+$2+','+$3" ^
/m /jmatch /o output.csv
-- OUTPUT --
ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22
It is easy to add the header line that lists the column names:
type *.txt 2>&1 | jrepl ^
"OS Username:\s*(.*?)$[\s\S]*?GIS Username:\s*(.*?)\s[\s\S]*?Log-In Time:\s*(.*?)$" ^
"$1+','+$2+','+$3" ^
/jbeg "output.WriteLine('OS Username,GIS Username,Login Time')" ^
/m /jmatch /o output.csv
-- OUTPUT --
OS Username,GIS Username,Login Time
ADIELA,adiela,21/07/2014 06:37:20
allanj1,allanj,17/12/2014 11:44:22

This was a good one.
Here is how I solved it:
#ECHO OFF
SETLOCAL EnableExtensions EnableDelayedExpansion
SET SourceFile="C:\SourceFile.txt"
SET OutputFile="C:\List.txt"
SET TempFile1="%TEMP%\1.txt"
SET TempFile2="%TEMP%\2.txt"
SET TempFile3="%TEMP%\3.txt"
REM Initialize files.
ECHO Header>%TempFile1%
ECHO Header>%TempFile2%
ECHO Header>%TempFile3%
IF EXIST %OutputFile% DEL %OutputFile%
REM Build a list of each value.
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "OS" %SourceFile%`) DO ECHO %%B>>%TempFile1%
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "GIS" %SourceFile%`) DO ECHO %%B>>%TempFile2%
FOR /F "usebackq tokens=1,* delims=:" %%A IN (`FINDSTR /L "Log-In" %SourceFile%`) DO ECHO %%B>>%TempFile3%
REM All temp files should have the same number of entries.
REM Concatenate them with a comma.
SET Skip=1
:ProcessLine
REM Keep going until we find the first empty entry.
REM This means we reached the end of the list.
SET "OSUserName="
SET "GISUserName="
SET "LogInTime="
REM Only set the first line.
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile1%) DO IF "!OSUserName!"=="" SET OSUserName=%%A
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile2%) DO IF "!GISUserName!"=="" SET GISUserName=%%A
FOR /F "usebackq tokens=* skip=%Skip% delims= " %%A IN (%TempFile3%) DO IF "!LogInTime!"=="" SET LogInTime=%%A
ECHO %OSUserName%
REM Check for the end of the list.
IF "%OSUserName%"=="" GOTO Finish
REM Add to the output.
ECHO %OSUserName%,%GISUserName%,%LogInTime%>>%OutputFile%
REM Increment counter and loop.
SET /A Skip=%Skip%+1
GOTO ProcessLine
:Finish
REM Cleanup.
IF EXIST %TempFile1% DEL %TempFile1%
IF EXIST %TempFile2% DEL %TempFile2%
IF EXIST %TempFile3% DEL %TempFile3%
ENDLOCAL

This builds your csv directly from the source files (without a temporary file):
#echo off
setlocal enabledelayedexpansion
REM write first line:
echo OSUser;GISUser;LoginTime >out.csv
REM for every .txt file:
for %%i in (*.txt) do (
REM add the three strings:
set "x="
for /f "tokens=1,* delims=:" %%a in ('findstr "Username Log-In" %%i') do set x=!x!%%b;
REM delete any "two consecutive spaces":
set x=!x: =!
REM delete TABs ( it's a TAB between : and = ):
set x=!x: =!
REM delete last ; (if it disturbes you):
set x=!x:~0,-1!
REM write it to the file:
echo !x!>>out.csv
)

Related

Trying to merge files with logic to fill in missing data. * building a flat database?

I'm trying to merge files with logic, to fill in missing data. I'm
having issues with if errorlevel
#echo off
SETLOCAL enableDelayedExpansion
del /q porttemp.csv
del /q database.csv
rem CMD BATCH-FILE Trying to merge files with logic to fill missing data.
rem * building a flat database ?
rem *** Reading temp3.csv looking for match in temp4.csv, ie 34/0/23
rem *** if not found trying to add "blank" to output file
echo ********* Phase 1 begin *******
:part1
FOR /F "tokens=1,2,3,4* delims=," %%a IN (temp3.csv) do (
rem parse thru temp3.csv
echo LOOP 1 - %%a,%%b,%%c,%%d
for /F "tokens=1,2* delims=, " %%M in (temp4.csv) do (
rem is %%a found in temp4.csv
rem if true output %%a,%%b,%%c,%%M
rem if false output %%a,%%b,%%c,blank
findstr %%a temp4.csv
if /I ERRORLEVEL EQU 0 (echo %%a,%%b,%%c,%%M >> porttemp.csv) ELSE (echo %%a,%%b,%%c,blank >> porttemp.csv)
echo Loop 2 - debug output - %ERRORLEVEL% -%%a,%%b,%%c vs %%M,%%N
pause
)
)
type porttemp.csv
temp3.csv contains:
Gi-34/0/10_,lpu,w-3-018ch1swA2p19_lag Gi-34/0/11_,lpu,prodca1_lan_sec
Gi-34/0/12_,lpu,prodca2_lan_sec Gi-34/0/13_,lpd, Gi-34/0/14_,lpd,
Gi-34/0/15_,lpd, Gi-34/0/16_,lpd, Gi-34/0/17_,lpd,
Gi-34/0/18_,lpu,aix_to_hmc Gi-34/0/19_,lpu,prodcafl1_lan_sec
Gi-34/0/02_,lpu,w-3-016ch1swA2p19_lag
Gi-34/0/20_,lpu,prodcafl2_lan_sec Gi-34/0/21_,lpu,prodcafl3_lan_sec
Gi-34/0/22_,lpu,prodcafl4_lan_sec Gi-34/0/24_,lpd,
Gi-34/0/25_,lpu,CHARONHOST2_DARLA Gi-34/0/26_,lpu,Centera_c001n03
Gi-34/0/27_,lpu,Centera_c001n01 Gi-34/0/28_,lpu,Centera_c001n02
Gi-34/0/29_,lpu,Centera_c001n04 Gi-34/0/03_,lpu,w-3-016ch2swA1p19_lag
Gi-34/0/30_,lpu,Centera_c002n03 Gi-34/0/31_,lpu,Centera_c002n02
Gi-34/0/32_,lpu,Centera_c002n04 Gi-34/0/33_,lpu,Centera_c002n01
Gi-34/0/34_,lpu,CHARONHOST2 Gi-34/0/35_,lpd, Gi-34/0/36_,lpd,
Gi-34/0/37_,lpd, Gi-34/0/38_,lpu,TMC_Flex7_cmm2
Gi-34/0/39_,lpu,TMC-TPC_Sec
temp4.csv file contains:
98be:947e:257c,Gi-34/0/18_ 5cf3:fc39:a194,Gi-34/0/23_
aa00:0400:64a4,Gi-34/0/25_ d43d:7e7d:8e4e,Gi-34/0/26_
d43d:7ec1:f280,Gi-34/0/27_ d43d:7e7d:9770,Gi-34/0/28_
Here's a version, similar to LotPings but with anything unnecessary for the actual end goal removed:
#Echo Off
SetLocal EnableDelayedExpansion
(For /F "UseBackQ Tokens=1-3 Delims=," %%A In ("temp3.csv") Do (Set "_=blank"
For /F "Delims=," %%D In ('Find /I "%%A "^<"temp4.csv"') Do Set "_=%%D"
Echo=%%A,%%B,%%C,!_!))>porttemp.csv
Type porttemp.csv
Remove the word blank on line 3 if you really do want nothing to be output after the comma.
IMHO you do over complicate things. If you set a var prior searching temp4.csv to blank and only process finds in temp4.csv there is no need for an if:
#echo off
SETLOCAL enableDelayedExpansion
del /q porttemp.csv
del /q database.csv
rem CMD BATCH-FILE Trying to merge files with logic to fill missing data.
rem * building a flat database ?
rem *** Reading temp3.csv looking for match in temp4.csv, ie 34/0/23
rem *** if not found trying to add "blank" to output file
echo ********* Phase 1 begin *******
:part1
FOR /F "tokens=1-4* delims=," %%a IN (temp3.csv) do (
rem parse thru temp3.csv
echo LOOP 1 - %%a,%%b,%%c,%%d
Set "BlankorM="
for /F "tokens=1,2* delims=, " %%M in (
'Findstr /I "%%a" temp4.csv'
) do Set "BlankorM=%%M"
echo %%a,%%b,%%c,!BlankorM! >> porttemp.csv
)
type porttemp.csv

Batchfile: read last lines from logfiles and copy them to a new file

This is my first posting so if the format is not as it supposed to be please excuse me for this. (Suggestions for
improvement are welcome.)
I am trying to create a batchfile that will read last lines from logfiles and copy them to a new file.
Until now I have found here a way to read the last line.
Code would be something like:
for /f %%i in ('find /v /c "" ^< someFile.txt') do set /a lines=%%i
set /a startLine=%lines% - 1
more /e +%startLine% someFile.txt > lastLines.txt
The above code works for one file at a time. What I need is to read the last line from all files in a known list and add this line to a new .csv file.
I have been using the following code for getting the 4th entry in the logfiles but it returns every line of every logfile:
for /f %%x in (%list%) do for /f "delims=.txt, tokens=4" %%i in (%%x.txt) do echo %%x, %%i >> output.csv
What I would need is a sort of combination of both but I don't know how to combine them and make the complete last line be copied to the .csv file.
===
#Magoo:
Thanx for your reaction.
In every logfile can be 1 to >100 lines with comma separated information. Something like:
"LOGON,6-1-2015,12:43:39,USERNAME,HOSTNAME,,,,192.168.209.242,00:21:5A:2E:64:5E"
The last code with the 4th entry was used to get a list of all accounts that had logged in to the computers. This code gave me a very large list of all logon/logoff events on all computerlogs I checked in %list%.
In %list$ I had all the names of logfiles I wanted to be checked. This returned all lines.
For a new batchfile I need only the last logon/logoff entry and I want the whole last line.
So I have a .txt file with the hostnames of all computers I need to examine.
This .txt file will be read line by line via the variable %list%.
From every logfile I need only the last line copied to an output file.
===
I just tried the solution offered by JosefZ. Unfortunately this does not work for me yet. No lastlines are copied to the resultfile. In the code I removed the extra entry for possible lastlines for there are no empty lines in the logs, I also added an entry for the hostname I want to be available in the result. JosefZ had the filename there:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "host=%%~x"
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=.\logs\%filename:&=^&%.txt"
echo %host%,%lastline%>>output.csv
goto :eof
The resultfile shows only the hostnames. I'll puzzle some more with this but all tips are welcome!
===
Got it!!!
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set filename= :: *empty previous filename*
set lastline= :: *empty previous lastline*
set "host=%%~x"
set "filename=.\logs\%host%.txt" :: *creating the filename from path+hostname+extention*
for /F "tokens=*" %%G in ('type "%filename%"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
echo %host%,%lastline%>>output.csv
goto :eof
Your approach with line numbering could fail if a file has more trailing empty lines. Fortunately for /F loop ignores (does not iterate) empty lines; let's put to use this feature: in the script used next practices:
disabledelayedexpansion to allow ! in file names
set "list=_listing.txt" where the _listing.txt contains list of file names (full path and extension .txt including), one file name on one line: got by dir /b /s *.txt>_listing.txt
type nul>files\output.csv to empty the output file (optional)
set "lastline=!!!file empty!!!" to initialize variable %lastline%; could be set "lastline=" as well
call :lline to process variables %filename% and %lastline%
set "filename=%filename:&=^&%" to allow & in file names
The script is as follows:
#ECHO OFF >NUL
#SETLOCAL enableextensions disabledelayedexpansion
type nul>files\output.csv
set "list=_listing.txt"
for /F "tokens=*" %%x in ('type "%list%"') do (
set "filename=%%~x"
set "lastline=!!!file empty!!!"
rem the whole line
for /F "tokens=*" %%G in ('type "%%~x"') do set "lastline=%%G"
rem the fourth token only
rem for /F "tokens=4" %%G in ('type "%%~x"') do set "lastline=%%G"
call :lline
)
:endlocal
#ENDLOCAL
goto :eof
:lline
set "filename=%filename:&=^&%"
echo %filename% %lastline%
rem >>files\output.csv
goto :eof
Sample _listing.txt file:
d:\bat\files\1exclam!ation.txt
d:\bat\files\2exc!lam!ation.txt
d:\bat\files\11per%cent.txt
d:\bat\files\12per%cent%.txt
d:\bat\files\17per%Gcent.txt
d:\bat\files\18per%%Gcent.txt
d:\bat\files\21ampers&nd.txt
d:\bat\files\22ampers&&nd.txt
Output:
d:\bat>lastlines
d:\bat\files\1exclam!ation.txt 0 15.01.2015 1:52:28.48 -15072 20465
d:\bat\files\2exc!lam!ation.txt 6 15.01.2015 1:52:28.50 3250 16741
d:\bat\files\11per%cent.txt -8 15.01.2015 1:52:28.50 -3692 27910
d:\bat\files\12per%cent%.txt !!!file empty!!!
d:\bat\files\17per%Gcent.txt 0 15.01.2015 1:52:28.56 14508 12374
d:\bat\files\18per%%Gcent.txt 1 15.01.2015 1:52:28.56 30540 26959
d:\bat\files\21ampers&nd.txt 15.01.2015 1:22:50.18
d:\bat\files\22ampers&&nd.txt 15.01.2015 1:22:50.18
Honestly, all that ballast is for (possibly) trailing empty lines in files and for (possibly) ! and & in file names only; all could be done with
for /f %%x in (%list%) do for /f "skip=%startLine% tokens=4" %%i in (%%x) do echo %%x, %%i >> output.csv
You should use a simple FOR to iterate a list of values, not FOR /F.
Something like the following should work:
#echo off
setlocal enableDelayedExpansion
>>output.csv (
for %%F in (
"file1.log"
"file2.log"
"file3.log"
etc.
) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
The quotes around the file names are there in case you get a name with spaces.
You could use your LIST variable if it looks something like
set LIST="file1.log" "file2.log" "file3.log" etc.
#echo off
setlocal enableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
more +!skip! %%F
)
)
If any of your file names contain the ! character, then you must toggle delayed expansion ON and OFF within your loop. Otherwise the delayed expansion will corrupt the names when %%F is expanded.
#echo off
setlocal disableDelayedExpansion
set LIST="file1.log" "file2.log" "file3.log" etc.
>>output.csv (
for %%F in (%LIST%) do (
for /f %%A in ('find /v /c "" <%%F') do set /a skip=%%A-1
setlocal enableDelayedExpansion
more +!skip! %%F
endlocal
)
)

Replace line in config file with batch afterward start exe

With a batch file, I want to change a value in a configuration file:
"title.connectionString" : "ServerIP",
ServerIP is the variable to be changed. So the batch file has to give people who use it an option to choose from 4 prefixed IPs. After they selected one of the 4 the IP, the config file has to be saved with new value and the batch file should run an executable.
Has anyone got an idea how I can do this with a batch file?
Easy, try this code:
#echo off
:start
Echo Select Ip:
Echo.
Echo 1. 10.0.0.0
Echo 2. 10.0.0.1
Echo 3. 10.0.0.2
Echo 4. 10.0.0.1
Echo.
Choice /c 1234 /m "Ip: " /n
set choice=%errorlevel%
set ip=
if %choice%==1 set ip=10.0.0.0
if %choice%==2 set ip=10.0.0.1
if %choice%==3 set ip=10.0.0.2
if %choice%==4 set ip=10.0.0.3
if "%ip%"=="" (Echo Error, null variable & goto :start)
ren config.txt config.tmp
setlocal Enabledelayedexpansion
for /f "tokens=*" %%a in (config.tmp) do (
set line=%%a
Echo !line:ServerIP=%ip%! >> config.txt
)
del config.tmp
And that should do what you want.
Mona
#echo off
setlocal enableextensions
call :replaceKeyValue "file.config" "title.connectionString" "123456789"
endlocal
exit /b
:replaceKeyValue file key value
setlocal enableextensions disabledelayedexpansion
ren "%~f1" "%~nx1.tmp" >nul && (
(for /f tokens^=1^,*^ delims^=^:^ eol^= %%k in ('findstr /n "^" ^<"%~f1.tmp"') do (
echo(%%l|findstr /c:"\"%~2\"" >nul && (
for /f "tokens=1 delims=:" %%v in ("%%l") do echo(%%~v : "%~3",
) || (
echo(%%l
)
)) > "%~f1"
del "%~f1.tmp" > nul
)
endlocal
This will handle the replacement of the value in the file. Monacraft answer shows a perfect way of selecting the required ip.
This will rename the file to file.tmp and for each line in the file (findstr /n is used to avoid lost of empty lines) it is tested agains the passed key. When required line is found, it is split using the colon (to keep the indentation) and value replaced with supplied value. All the non matching lines are echoed as is. All the output of the process is send to the original file and at end, the .tmp file is deleted.

'findstr' with multiple search results (BATCH)

This is based on my last question's script:, Directory mapout is not working (BATCH)
(For the whole script, click the link. However, you may only click the link if the following snip of code from "directory mapout is not working" does not really make sense to you)
<code>
cd temporary
set odir=%dir%
set /p cdir="DIRECTORY: "
set domap=%cdir%
title SONOROUS FILE SEARCHER: Mapping out...
echo PLEASE WAIT, MAPPING OUT DIRECTORY.
dir %domap% /a-d /b /s > "tempres.rsm"
echo Directory Mapout done
echo -----------------------------
echo DIRECTORY MAPOUT
set dirmapout=<tempres.rsm
echo %dirmapout%
echo -----------------------------
title SONOROUS FILE SEARCHER: Mapout done.
set /p "searchinput=Search Term: "
title SONOROUS FILE SEARCHER (Copyright 2013 by Sonorous)
for /f "delims=" %%a in ('findstr /i /L /c:"%searchinput%" "tempres.rsm" ') do set "found=%%a"
set proin=%found%
echo "%found%"
cd temporary
del "tempres.rsm"
</code>
I want the "for /f" command to output MANY search results from one search term.
Is the code not correctly formatted? Please message / comment on this question.
If you simply want to display the matching lines, then ditch the FOR /F altogether
title SONOROUS FILE SEARCHER (Copyright 2013 by Sonorous)
findstr /i /L /c:"%searchinput%" "tempres.rsm"
cd temporary
del "tempres.rsm"
If you need an "array" of matching lines, then:
:: Define the array of matching lines
set "foundCount=0"
for /f delims^=^ eol^= %%a in ('findstr /i /L /c:"%searchinput%" "tempres.rsm" ') do (
set /a "foundCount+=1"
setlocal enableDelayedExpansion
for %%N in (!foundCount!) do (
endlocal
set "found%%N=%%a"
)
)
:: Display the array values
setlocal enableDelayedExpansion
for /l %%N in (1 1 %foundCount%) do echo match %%N = !found%%N!

Deleting last n lines from file using batch file

How to delete last n lines from file using batch script
I don't have any idea about batch files, I am writing batch file for the first time.
How should I write this batch file?
For Windows7
Try it for
<Project_Name>
<Noter>
<Common>
<File>D:\Project_Name\Util.jar</File>
<File>D:\Project_Name\Noter.bat</File>
<File>D:Project_Name\Noter.xml</File>
<File>D:Project_Name\Noter.jar</File>
</Common>
<Project_Name>
<File>D:\Util.bat</File>
<File>D:\Util.xml</File>
<File>D:\log.bat</File>
</Project_Name>
</Noter>
<CCNET>
This the complete script for remove last N line
count the total line
set Line = Line - N , remain just processing lines number
#echo OFF
setlocal EnableDelayedExpansion
set LINES=0
for /f "delims==" %%I in (infile.txt) do (
set /a LINES=LINES+1
)
echo Total Lines : %LINES%
echo.
:: n = 5 , last 5 line will ignore
set /a LINES=LINES-5
call:PrintFirstNLine > output.txt
goto EOF
:PrintFirstNLine
set cur=0
for /f "delims==" %%I in (infile.txt) do (
echo %%I
::echo !cur! : %%I
set /a cur=cur+1
if "!cur!"=="%LINES%" goto EOF
)
:EOF
exit /b
Here call:PrintFirstNLine > output.txt will give the output in an external file name as output.txt
Output for sample Input
<Project_Name>
<CBA_Notifier>
<Common>
<File>D:\CBA\CBA_Notifier\Project_Name\IPS-Util.jar</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.bat</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.xml</File>
<File>D:\CBA\CBA_Notifier\Project_Name\Notifier.jar</File>
</Common>
<Project_Name>
<File>D:\CBA\CBA_Notifier\IPS-Util.bat</File>
remove last 5 line
Update
:PrintFirstNLine
set cur=0
for /F "tokens=1* delims=]" %%I in ('type "infile.txt" ^| find /V /N ""') do (
if "%%J"=="" (echo.) else (
echo.%%J
set /a cur=cur+1
)
if "!cur!"=="%LINES%" goto EOF
)
This script will takes 1 arguement, the file to be trunkated, creates a temporary file and then replaces the original file with the shorter one.
#echo off
setlocal enabledelayedexpansion
set count=
for /f %%x in ('type %1 ^| find /c /v ""') do set /a lines=%%x-5
copy /y nul %tmp%\tmp.zzz > nul
for /f "tokens=*" %%x in ('type %1 ^| find /v ""') do (
set /a count=count+1
if !count! leq %lines% echo %%x>>%tmp%\tmp.zzz
)
move /y %tmp%\tmp.zzz %1 > nul
If the original file is 5 or less lines, the main output routine will noT create a file. To combat this, I use the copy /y null to create a zero byte file.
If you would rather not have an empty file, just remove the copy /y nul line, and replace it with the following line:
if %lines% leq 0 del %1
You should use one method or the other, otherwise source files with 5 or less lines will remain untouched. (Neither replaced or deleted.)
to delete last lines from your file,
1 copy starting lines that are needed from file like from- e:\original.txt
2 paste them in new file like- e:\new\newfile1.txt
code is thanks to the person giving me this code:
remember all may be done if you have motive and even blood hb =6. but help of nature is required always as you are a part of it
#echo off & setLocal enableDELAYedeXpansion
set N=
for /f "tokens=* delims= " %%a in (e:\4.txt) do (
set /a N+=1
if !N! gtr 264 goto :did
e:\new4.txt echo.%%a
)
:did
if you have 800 files then use excel to make code for 800 and then copy it to notepad and using Ctrl+h replace space with no space. then rename file as haha.bat . run in folder with files numbered 1.txt 2.txt 3.txt etc. any enquirers welcome Erkamaldev#gmail.com " Long Live Bharata"
A slow method with less coding:
set input=file.txt
set remove=7
for /f "delims=" %i in ('find /c /v "" ^< "%cd%\%input%"') do set lines=%i
set /a lines-=remove
for /l %i in (1,1,!lines!) do findstr /n . log.txt | findstr /b %i:
May be redirected to a file.
Each line is prefixed with the line number; may be removed with extra coding.
A faster version with /g flag in my answer at:
How to split large text file in windows?
Tested in Win 10 CMD, on 577KB file, 7669 lines.

Resources