<http://www.netikka.net/tsneti/info/tscmd151.htm>
Copyright © 2003- by Prof. Timo Salmi  
Last modified Fri 13-Feb-2015 13:54:20

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



151} Extract the lines of a text file from between two marker-lines?

> I have a text file that is like:
>
> date = OCT0606
> asdf
> sdaf
> asdfasdgsdgh
> asdfsdfasdg
> START-OF-DATA
> asdfasdfg
> asdfgdfgsfg
> sadfsdfgsa
> asdfgsdfg
> END-OF-DATA
> asdfgalsdkdfklmlkm
> asdfgasdfg
>
> I need to clear everything from this file except the data between
> the START-OF-DATA and END-OF-DATA using a batch file.

  @echo off & setlocal enableextensions enabledelayedexpansion
  set source=C:\_M\MyData.txt
  set flagStart=
  set flagEnd=
  for /f %%a in ('type "%source%"') do (
    echo %%a|find "START-OF-DATA">nul
    if !errorlevel! EQU 0 set flagStart=true
    echo %%a|find "END-OF-DATA">nul
    if !errorlevel! EQU 0 set flagEnd=true
    if defined flagStart if not defined FlagEnd (
      echo %%a|find /v "START-OF-DATA"
      )
    )
  endlocal & goto :EOF

Actually the lines
  set flagStart=
  set flagEnd=
are superfluous, but they depict the logic.

The output:
  C:\_D\TEST>cmdfaq
  asdfasdfg
  asdfgdfgsfg
  sadfsdfgsa
  asdfgsdfg

Also as below. The first is inclusive, the second exclusive
  sed -n "/START-OF-DATA/,/END-OF-DATA/p" %source%

  sed "1,/START-OF-DATA/d" %source%|sed "/END-OF-DATA/,$d"

The problem can also be solved with a command-line driven VBScript filter. Note a crucial difference between the sed and the VBScript solutions. If there several START-OF-DATA END-OF-DATA pairs within the source files the sed solution will extract all the data in between, the VBScript solution only the first pair encountered. - First an exclusive version, i.e. the beginning and the ending marker are excluded from the output.
  @echo off & setlocal enableextensions
  ::
  :: Your parameters

  set myfile_=C:\_M\MyData.txt
  set cut1=START-OF-DATA
  set cut2=END-OF-DATA
  ::
  :: Build a Visual Basic Script

  set vbs_=%temp%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6

  cscript //nologo "%vbs_%" "%cut1%" "%cut2%" < "%myfile_%"
  ::
  :: Clean up

  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '

  set arg = WScript.Arguments 'VBS
  startTrigger = arg(0) 'VBS
  endTrigger = arg(1) 'VBS
  '
  startFound = False 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    line = WScript.StdIn.ReadLine 'VBS
    If InStr (1,line,endTrigger,vbTextCompare) > 0 Then Exit Do 'VBS
    If startFound Then WScript.StdOut.WriteLine line 'VBS
    If InStr (1,line,startTrigger,vbTextCompare) > 0 Then startFound = True 'VBS
  Loop 'VBS

What if you wish to include the beginning and the ending line? (Unrelated, this snippet has a slightly different setting of markers.)
  @echo off & setlocal enableextensions
  ::
  :: Your parameters

  set myfile_=C:\_M\MyData.vcf
  set cut1=BEGIN:VCARD
  set cut2=END:VCARD
  ::
  :: Build a Visual Basic Script (use your own temporary folder, if you have one)

  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set vbs_=%temp_%\tmp$$$.vbs
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%vbs_%"
  ::
  :: Run it with Microsoft Windows Script Host Version 5.6

  cscript //nologo "%vbs_%" "%cut1%" "%cut2%" < "%myfile_%"
  ::
  :: Clean up

  for %%f in ("%vbs_%") do del %%f
  endlocal & goto :EOF
  '
  '............................................
  'The Visual Basic Script
  '

  set arg = WScript.Arguments 'VBS
  startTrigger = arg(0) 'VBS
  endTrigger = arg(1) 'VBS
  'Note the subtly different order and composition of the commands
  startFound = False 'VBS
  Do While Not WScript.StdIn.AtEndOfStream 'VBS
    line = WScript.StdIn.ReadLine 'VBS
    If InStr (1,line,startTrigger,vbTextCompare) > 0 Then startFound = True 'VBS
    If InStr (1,line,endTrigger,vbTextCompare) > 0 Then 'VBS
      WScript.StdOut.WriteLine line 'VBS
      Exit Do 'VBS
    End If 'VBS
    If startFound Then WScript.StdOut.WriteLine line 'VBS
  Loop 'VBS

VCF Cutter: A real-life dilemma. I have from my Samsung Galaxy S4 Mini smartphone its address book as one big exported VCF file with almost five hundred names on it. How do I split that behemoth into individual Vcard files? This time no command-line script purity, but whatever gets my task done and saves my day. The answer lies in G(nu)awk. After several hours of effort, the solution was deceptively brief. Also note that because of the compostion of the Contacts.vcf sourcefile it is sufficient to cut at the "BEGIN:VCARD" starting lines.
  @echo off & setlocal enableextensions
  set myfile_=C:\_M\Contacts.vcf
  unxgawk "/BEGIN:VCARD/{x=++i}{a=\"000\"x}{p=length(a)}{a=substr(a,p-3,p)}{printf\"%%s\n\",$0>\"Vcard\"a\".vcf\"}" "%myfile_%"
  endlocal & goto :EOF

Files produced:
  Vcard0001.vcf Vcard0002.vcf Vcard0003.vcf Vcard0004.vcf Vcard0005.vcf
  Vcard0006.vcf Vcard0007.vcf Vcard0008.vcf Vcard0009.vcf Vcard0010.vcf
  Vcard0011.vcf Vcard0012.vcf Vcard0013.vcf Vcard0014.vcf Vcard0015.vcf
  ...
  Vcard0451.vcf Vcard0452.vcf Vcard0453.vcf Vcard0454.vcf

The above can be rewritten in a more legible and script-like code as
  @echo off & setlocal enableextensions
  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set awkcmd_=%temp_%\tscmd$$$.awk
  set myfile_=C:\_M\Contacts.vcf
  >  "%awkcmd_%" echo /BEGIN:VCARD/{x=++i}
  >> "%awkcmd_%" echo {a="000"x}
  >> "%awkcmd_%" echo {p=length(a)}
  >> "%awkcmd_%" echo {a=substr(a,p-3,p)}
  >> "%awkcmd_%" echo {printf "%%s\n",$0 ^> "Vcard"a".vcf"}
  unxgawk -f "%awkcmd_%" "%myfile_%"
  for %%f in ("%awkcmd_%") do if exist %%f del %%f
  endlocal & goto :EOF

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups Oct 9 2006, 11:57 pm [M]
  Split contacts using VCF Cutter to export to a Nokia phone