Extract specific lines (including Empty lines)

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Extract specific lines (including Empty lines)

#1 Post by abc0502 » 01 Oct 2012 08:36

I'm working on a batch here: http://www.dostips.com/forum/viewtopic.php?f=3&t=3821

The problem is {empty Lines},
all empty lines will be skipped, but i found these two topics, here and here
These codes enable you to echo the empty lines using "set /p" command,
but my problem is how can i just take specific lines from a file, like taking lines in range (line5 till line 11) and discard the rest

any idea ?

aGerman
Expert
Posts: 4745
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Extract specific lines (including Empty lines)

#2 Post by aGerman » 01 Oct 2012 10:08

Try this:

Code: Select all

@echo off &setlocal
set "file=test.txt"
set /a from=5
set /a till=11

for /f %%i in ('type "%file%"^|find /v /c ""') do if %till% gtr %%i set /a till=%%i
set /a skip=from-1

setlocal EnableDelayedExpansion
<"!file!" (
  for /l %%i in (1 1 %skip%) do set /p "="
  for /l %%i in (%from% 1 %till%) do (
    set "ln="
    set /p "ln="
    echo(!ln!
  )
)
endlocal
pause

Regards
aGerman

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Extract specific lines (including Empty lines)

#3 Post by abc0502 » 01 Oct 2012 10:17

@aGerman, that is brilliant :D
This code works perfectly,
I spent the whole day searching and coding to come up with something like that, thanks :)

Edit:
I converted it to a function, soany one can use it in his code:

Code: Select all

:Extract 
:: >>> Credits Goes to: aGerman @ Dostips.com <<<
:: Call :Extract "<source_file>" "<start_line>" "<end_line>"
:: <source_file> .. is the file where the text will be extracted
:: <start_line>  .. is from which line start extracting
:: <end_line>    .. is at which line end extracting

set "file=%~1"
set "from=%~2"
set "till=%~3"

For /F %%i in ('type "%file%"^|find /v /c ""') do if %till% gtr %%i set /a till=%%i
set /a skip=from-1

Setlocal EnableDelayedExpansion
<"!file!" (
  for /l %%i in (1 1 %skip%) do set /p "="
  for /l %%i in (%from% 1 %till%) do (
    set "ln="
    set /p "ln="
    echo(!ln!
  )
)
endlocal
goto :eof

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Extract specific lines (including Empty lines)

#4 Post by abc0502 » 02 Oct 2012 02:59

Is there a way i can use in an if_statement to determine if the line is empty or not,

like :
if !line! EQU !empty! ( Do command
) else ( Do another command )

I tried to use the string replace method here
so i replaced the !ln! with !ln:%word1%=%word2%!
it work fine only if the line wasn't empty but on empty line it just write the right part of the <!ln!> variable <%word1%=%word2%>

I searched the forum and found this method to get all empty lines + there line number from a file here

So i tried this:

Code: Select all

@echo off
cls
setlocal EnableDelayedExpansion
:: Note that the empty space between [^ and ] is a one <space> and one <tab>
for /f "tokens=2 delims=:" %%A in ('findstr /n /r /v /c:"[^    ]" "t1.txt"') Do (
   <"t1.txt" (
   for /l %%i in (1 1 5) do set /p "="
   for /l %%i in (6 1 11) Do (
      set "ln="
      set /p "ln="
      if "!ln!" EQU "%%A" ( echo(!ln!
      ) Else ( echo(!ln:sun=run! )
   )
)
)
pause

but still can't get it to be set to a variable and compared with the line

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Extract specific lines (including Empty lines)

#5 Post by abc0502 » 02 Oct 2012 03:12

Soo Sorry about that, I just found a way to do that.
with the same code i posted, but with small tweak,
the tokens will be "1,2", and the delims ":"
now the %%A will be the line number of the empty line, and the %%B will be the empty line (what it represent empty space)

when comparing the !ln! with the %%A:%%B we add extra <%%A:> to the !ln! like this:

Code: Select all

IF "%%A:!ln!" EQU "%%A:%%B" ( Echo( !ln!
) Else ( Echo( !ln:sun=run! )

that way when it come to empty line it will match exactly the form of <%%A:%%B>, and
when come to a non empty line, it won't and will do the second command.

The full code is like that:
This will take the lines from 6 till 11 and replace all existance of the word "sun" into "run" in the file "t1.txt"

Code: Select all

@echo off
cls
setlocal EnableDelayedExpansion
for /f "tokens=1,2 delims=:" %%A in ('findstr /n /r /v /c:"[^    ]" "t1.txt"') Do (
   <"t1.txt" (
   for /l %%i in (1 1 5) do set /p "="
   for /l %%i in (6 1 11) Do (
      set "ln="
      set /p "ln="
      if "%%A:!ln!" EQU "%%A:%%B" ( echo(!ln!
      ) Else ( echo(!ln:test=tost! )
   )
)
)
pause


BUT still one problem, the lines in range 5:11 repeated with the same number of empty lines that exist in that file

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Extract specific lines (including Empty lines)

#6 Post by foxidrive » 02 Oct 2012 03:49

This task should use SED I think.

Code: Select all

@echo off
(
echo 1
echo 2
echo 3
echo 4
echo 5
echo 6
)>file.txt
sed 2,5!d file.txt


Screen output

2
3
4
5



Then it's a matter of counting ranges and use sed to assemble the output file.

abc0502
Posts: 1007
Joined: 26 Oct 2011 22:38
Location: Egypt

Re: Extract specific lines (including Empty lines)

#7 Post by abc0502 » 02 Oct 2012 03:57

Thanks foxidrive, i found a way, :D

here is is, and sorry for long description :) but in case any one else needed it later

Code: Select all

@echo off
cls
setlocal EnableDelayedExpansion
<"t1.txt" (
    for /l %%a in (1 1 5) do set /p "="
        for /f "tokens=1,2 delims=:" %%A in ('findstr /n /r /v /c:"[^    ]" "t1.txt"') Do (
       for /l %%i in (1 6 6) Do (
           set "ln="
      set /p "ln="
      If "%%A:!ln!" EQU "%%A:%%B" ( echo(!ln!
      ) else ( echo(!ln:test=toost! )
            )
        )
)
pause


First Loop :

Code: Select all

 for /l %%a in (1 1 5) do set /p "=" 
to determine how many lines to skip from the begining of the file, we skip here from line <1> to line <5> (line 5 included)

Second Loop :

Code: Select all

 for /f "tokens=1,2 delims=:" %%A in ('findstr /n /r /v /c:"[^    ]" "t1.txt"') Do ( 
to get all empty lines in this format <line_number: > , the space after : is just for representing the emptiness.

Third For Loop:

Code: Select all

for /l %%i in (1 6 6) Do ( 
In this for loop i changed aGerman code a bit, after we skipped the first 5 lines, any lines set here must start from the begining <1>, the end line will be the how many lines to take and stop at, which wil be <6> and we step from <1> to <6> with the same amount of the end line number
which will be <6>,
so based on aGerman post this for loop can be put like this

Code: Select all

set /a till = till - from
for /l %%i in (1 %till% %till%) Do (

Post Reply