0

I'm looking to remove the last 11 (and always 11) lines of my .csv file through a batch file and preferably do it without creating a newly named file. I found the below to remove the first 3 lines but I'm not sure how to modify this to remove the last 11. Any ideas? Thanks for your help!

@echo off
set "csv=MyFile.csv"
more +3 "%csv%" >"%csv%.new"
move /y "%csv%.new" "%csv%" >nul
slybitz
  • 689
  • 1
  • 7
  • 18
  • Possible duplicate of [Windows Batch, how to remove first line and last line and save as a new text file](http://stackoverflow.com/questions/31444879/windows-batch-how-to-remove-first-line-and-last-line-and-save-as-a-new-text-fil) – Thomas Weller Feb 13 '17 at 19:24
  • Not a duplicate in that I'm asking to remove just last 11 lines, and also don't want to save as a new text/csv file if possible. Thanks! – slybitz Feb 13 '17 at 19:32
  • @Squashman: That is a plan for skipping the first 11 lines, not removing the ***last*** 11 lines. – abelenky Feb 13 '17 at 19:50
  • Guys, get yourself [UnxUtils](http://unxutils.sourceforge.net) and don't create a cmd maintenance nightmare - with `head` and `tail` it's a no-brainer. – marabu Feb 13 '17 at 19:55
  • 4
    Comments that essentially say, *"Go get this tool"* are not appropriate for a programming-help site. – abelenky Feb 13 '17 at 20:03
  • @marabu that is not always possible in a work or production environment. – Squashman Feb 13 '17 at 20:15
  • If you can remove 1 line at the end, you can also remove 11 lines. Other than that, the tailhead.bat seems to be able to do what you need. – Thomas Weller Feb 13 '17 at 22:38
  • Possible duplicate of http://stackoverflow.com/questions/12345964/deleting-last-n-lines-from-file-using-batch-file – Thomas Weller Feb 13 '17 at 22:40

3 Answers3

1

The following code snippet does what you want, using a temporary file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_CSV_FILE=%~1" & rem // (specify CSV file here; `%~1` is first argument)
set "_NUM_FRST=0"   & rem // (specify number of lines to remove from beginning)
set "_NUM_LAST=11"  & rem // (specify number of lines to remove from end)

rem // Count number of available lines in file:
for /F %%C in ('^< "%_CSV_FILE%" find /C /V ""') do set /A "COUNT=%%C"
set /A "COUNT-=_NUM_LAST"
rem /* Process file, regarding and maintaining empty lines;
rem    lines must be shorter than about 8190 bytes: */
> "%_CSV_FILE%.tmp" (
    set /A "INDEX=0"
    for /F "delims=" %%L in ('findstr /N "^" "%_CSV_FILE%"') do (
        set /A "INDEX+=1"
        set "LINE=%%L"
        setlocal EnableDelayedExpansion
        if !INDEX! GTR %_NUM_FRST% if !INDEX! LEQ %COUNT% echo(!LINE:*:=!
        endlocal
    )
)
rem // Overwriting original file:
> nul move /Y "%_CSV_FILE%.tmp" "%_CSV_FILE%"

endlocal
exit /B

The following approach does not use a temporary file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_CSV_FILE=%~1" & rem // (specify CSV file here; `%~1` is first argument)
set "_NUM_FRST=0"   & rem // (specify number of lines to remove from beginning)
set "_NUM_LAST=11"  & rem // (specify number of lines to remove from end)

rem // Count number of available lines in file:
for /F %%C in ('^< "%_CSV_FILE%" find /C /V ""') do set /A "COUNT=%%C"
set /A "COUNT-=_NUM_LAST"
rem /* Process file, regarding and maintaining empty lines;
rem    lines must be shorter than about 8190 bytes: */
set /A "INDEX=0"
for /F "delims=" %%L in ('findstr /N "^" "%_CSV_FILE%" ^& ^> "%_CSV_FILE%" rem/') do (
    set /A "INDEX+=1"
    set "LINE=%%L"
    setlocal EnableDelayedExpansion
    if !INDEX! GTR %_NUM_FRST% if !INDEX! LEQ %COUNT% >> "!_CSV_FILE!" echo(!LINE:*:=!
    endlocal
)

endlocal
exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • This still writes to a new file, which the poster specifically said was to be avoided. – abelenky Feb 13 '17 at 21:13
  • 1
    @abelenky, it writes a temporary file and moves it onto the original one finally; I added a variant without a temporary file meanwhile... – aschipfl Feb 13 '17 at 21:24
0

Here is a simple command to count the lines in a file.

However, I do not see anyway to truncate the file without writing to a separate intermediate file.

@echo off
for /F "delims=[]" %%a in ('find /N /V "" myFile.TXT') do set LINE_COUNT=%%a
echo %LINE_COUNT%
abelenky
  • 63,815
  • 23
  • 109
  • 159
-3

Replace the line more +3 "%csv%" >"%csv%.new" by head -n -11 "%csv%" > "%csv%.new"

  • I missed to mention that I have Gow (Gnu On Windows) installed on my machine. If you have privileges to do this follow you'll find the link : https://blogs.msdn.microsoft.com/matt-harrington/2012/06/03/from-unix-to-windows-run-gnu-commands-on-windows-with-gow If you won't to deploy the entire executables, copy just the file C:\Program Files (x86)\Gow\bin\head.exe. – Haroldo Ribeiro Gomes Feb 13 '17 at 20:18