Can anyone help with a BAT file which will open a txt file and delete
the first four lines and the last five lines. The text file has a
header and footer which needs to be removed:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
NotDashEscaped: You need GnuPG to verify this message
I have this code which deletes the first four lines (see below) does
anyone have something I can add to it to delete the last 8 lines?
Thanks in advance,
Brett
Code to delete the first 4 lines:
@echo off
setLocal EnableDelayedExpansion
if exist *.new del *.new
for /f "tokens=* delims= " %%A in ('dir /b *.txt') do (
set NAME=%%~nA
set fileNAME=%%A
for /f "tokens=* skip=4 delims= " %%L in (!fileNAME!) do (
echo %%L >> !NAME!.new
)
)
::==
Take a look at the 'Batch file information and FAQs' posted here every week
and posted directly before your post on t5his occasion.
You will probably be looking at ideas from:
"23} How do I get the n'th, the first and the last line of a text file?"
Doing this in a pure batch file can be tricky because of the well-known
"poison character syndrome". A more robust solution could be based on a VB
Script program. You also need to think carefully how you want to handle the
condition that arises when your input file has fewer than 9 lines.
Here is a pure VB Script solution plus its equivalent as a hybrid batch
file. In the VB Script code you must adjust lines 1 .. 3 to suit your
environment, then remove the line numbers. In the batch file you must adjust
adjust lines 2 .. 4 before removing the line numbers.
[01] sFolder = "d:\Mon"
[02] iHeader = 4
[03] iTrailer = 5
[04]
[05] Set oFSO = CreateObject("Scripting.FileSystemObject")
[06] Set oFolder = oFSO.GetFolder(sFolder)
[07] sNames = ""
[08] For Each oFile In oFolder.Files
[09] sNames = sNames & oFile.Path & "|"
[10] Next
[11] aNames = Split(sNames, "|")
[12]
[13] For n = 0 To UBound(aNames) - 1
[14] If oFSO.GetFile(aNames(n)).Size > 0 Then
[15] p = InStrRev(aNames(n), ".")
[16] sNewName = Left(aNames(n), p) & "new"
[17] Set oInFile = oFSO.OpenTextFile(aNames(n))
[18] aData = Split(oInFile.ReadAll, VbCrLf)
[19] If UBound(aData) >= iHeader Then
[20] Set oOutFile = oFSO.OpenTextFile(sNewName, 2, True)
[21] For i = iHeader + 1 To UBound(aData) - iTrailer
[22] oOutFile.WriteLine aData(i)
[23] Next
[24] oOutFile.Close
[25] End If
[26] oInFile.Close
[27] End If
[28] Next
[01] @echo off
[02] set Header=4
[03] set Trailer=5
[04] set Folder=d:\Mon
[05] set Scr=c:\TempVBS.vbs
[06] set VB=echo^>^>%Scr%
[07] cd 1>nul 2>%Scr%
[08] %VB% Set oFSO = CreateObject("Scripting.FileSystemObject")
[09] %VB% Set oFolder = oFSO.GetFolder("%Folder%")
[10] %VB% sNames = ""
[11] %VB% For Each oFile In oFolder.Files
[12] %VB% sNames = sNames ^& oFile.Path ^& "^|"
[13] %VB% Next
[14] %VB% aNames = Split(sNames, "^|")
[15] %VB% For n = 0 To UBound(aNames) - 1
[16] %VB% If oFSO.GetFile(aNames(n)).Size ^> 0 Then
[17] %VB% p = InStrRev(aNames(n), ".")
[18] %VB% sNewName = Left(aNames(n), p) ^& "new"
[19] %VB% Set oInFile = oFSO.OpenTextFile(aNames(n))
[20] %VB% aData = Split(oInFile.ReadAll, VbCrLf)
[21] %VB% If UBound(aData) ^>= iHeader Then
[22] %VB% Set oOutFile = oFSO.OpenTextFile(sNewName, 2, True)
[23] %VB% For i = %Header% + 1 To UBound(aData) - %Trailer%
[24] %VB% oOutFile.WriteLine aData(i)
[25] %VB% Next
[26] %VB% oOutFile.Close
[27] %VB% End If
[28] %VB% oInFile.Close
[29] %VB% End If
[30] %VB% Next
[31] cscript //nologo %Scr%
[32] del %Scr%
In my opinion clean batch is a not nice tool to do this. There are to
many underwater stouns, such as empty strings, special simbols and
etc.
Sed.exe is the best solution.
@echo off
setlocal
for /f "tokens=2 delims=:" %%i in ('find /c /v "" 1.txt') do set /a
last=%%i-5
sed -i -n "5,%last% p" 1.txt
Covered e.g. in http://www.netikka.net/tsneti/info/tscmd023.htm
All the best, Timo
--
Prof. Timo Salmi mailto:t...@uwasa.fi ftp & http://garbo.uwasa.fi/
Hpage: http://www.uwasa.fi/laskentatoimi/english/personnel/salmitimo/
Department of Accounting and Finance, University of Vaasa, Finland
Useful CMD script tricks http://www.netikka.net/tsneti/info/tscmd.htm
This solution developed using XP
It may work for NT4/2K
----- batch begins -------
[1]@echo off
[2]del outlines.txt 2>nul
[3]set droptop=4
[4]for /f %%i in ( ' find /c /v "" ^<lines.txt ' ) do set /a dropend=%%i-8
[5]for /f "skip=%droptop%tokens=1*delims=][" %%i in ( ' find /n /v ""
^<lines.txt ' ) do if %%i leq %dropend% >>outlines.txt echo\%%j
[6]for %%i in (droptop dropend) do (set %%i=)
------ batch ends --------
Lines start [number] - any lines not starting [number] have been wrapped and
should be rejoined. The [number] that starts the line should be removed
The spaces surrounding the single-quotes are for emphasis only. The SPACES
are not required but the single-quotes ARE required.
Any leading "[" or "]" on data lines will be dropped.
The '4' on line [3] is the number of lines at the top to drop.
The '8' on line [4] is the number of lines to drop at the end.
> Hello,
>
> Can anyone help with a BAT file which will open a txt file and delete the
> first four lines and the last five lines. The text file has a header and
> footer which needs to be removed:
Normally one would use head and tail for that:
tail --lines=+4 < source | head --lines=-5 > target
head and tail can be found in the GnuWin32 CoreUtils collection:
<http://gnuwin32.sourceforge.net/packages/coreutils.htm>
Help for most GnuWin utilities is --help, or -h.
--
T.E.D. (tda...@mst.edu)
set "HEAD=2"
set "TAIL=2"
:-
set /a HT=HEAD+TAIL
for /f "delims=" %%x in (
'
dir/b/a-d "*.txt"
'
) do (call:_ParseLine_ "%%x")
pause
exit
:_ParseLine_
setlocal enabledelayedexpansion
if ["%~1"]==[""] goto:eof
for /f "tokens=1* delims=:" %%A in (
'
findstr -n . %1
'
) do (set T.Line=%%A)
set /a VERIF=T.LINE-HT
If !VERIF! LEQ 0 (call:ERROR %1)
set /a CNT=!T.LINE!-%TAIL%
for /f "delims=" %%b in (
'
type %1
'
) do (
set /a NB.LINE+=1
if !NB.LINE! GTR !HEAD! if !NB.LINE! LEQ !CNT! (echo.%%b) >> "Output_
%~nx1"
)
shift
endlocal
goto:_ParseLine_
:ERROR
echo Le fichier %1 ne peut pas etre traiter
echo Nombre insuffisants: %T.LINE% Lignes
echo.
goto:EOF
Out of curiosity I tested the two pure batch file solutions posted here.
Billious' solution generates the desired result and appears to work for all
"poison" character combinations that I tried. The solution presented by
"I'm_Here" is suffers from the usual batch file problems:
- It suppresses blank lines.
- It trips over poison characters.
- If fails to delete the five trailing lines.
It also uses an "exit" command when "goto :eof" or "exit /b" would be more
appropriate (because "exit" closes the current console session, which may
not be desirable).
Here are the execution times for a single 100 kByte text file:
- Billious' batch file: 11.5 seconds
- I'm_Here's batch file: 11.75 seconds
- Pure VB Script: 0.38 seconds
There appears to be a big penalty when using a batch file solution for
medium to large files.
if you can use vbscript, then please use it
Set objFS = CreateObject("Scripting.FileSystemObject")
strFile = "c:\test\file.txt"
Set objFile = objFS.OpenTextFile(strFile)
strData = objFile.ReadAll
s = Split(strData,vbCrLf)
For i=5 To UBound(s)-5
WScript.Echo s(i)
Next
on the command line
c:\test> cscript /nologo myscript.vbs