1

I want to create a batch file that will read a txt file containing text similar to (it will all be on 1 line):

"http://schemas.google.com/g/2005#event"}],"title":{"$t":"Test Begins","type":"text"},"content":{"$t":"","type":"text"},"link":[{"rel":"alternate","type":"text/html","href":"http://www.google.com/calendar/event?eid=XzhkOWxjZ3JmZHByNmFzams2MWhtNGU5azY4c200cDfr45yxN65kYjE2cGhqNGMxbDY4cjNjZWIxYzhwamNlMzE2Z28wIGFkbWluQGJodWpkaGFtLm9yZw","title":"alternate"},{"rel":"self","type":"application/atom+xml","href":"http://www.google.com/calendar/feeds/admin%40test.org/public/full/_8d9lcgrfdpr6asjk61hm4e9k68sm4p336oq62db16phj4c1l63erceb1c8pjce316go0"}],"author":[{"name":{"$t":"admin@test.org"},"email":{"$t":"admin@test.org"}}],"gd$comments":{"gd$feedLink":{"href":"http://www.google.com/calendar/feeds/admin%40test.org/public/full/_8d9lcgrfdpr6asjk61hm4e9k68sm4p336oq62db16phj4c1l68r3ceb1c8pjce316go0/comments"}},"gd$eventStatus":{"value":"http://schemas.google.com/g/2005#event.confirmed"},"gd$where":[{"valueString":""}],"gd$who":[{"email":"admin@test.org","rel":"http://schemas.google.com/g/2005#event.organizer","valueString":"admin@test.org"}],"gd$when":[{"endTime":"2014-01-17","startTime":"2014-01-16"}],"gd$transparency":{"value":"http://schemas.google.com/g/2005#event.opaque"},"gCal$anyoneCanAddSelf":{"value":"false"},"gCal$guestsCanInviteOthers":{"value":"true"},"gCal$guestsCanModify":{"value":"false"},"gCal$guestsCanSeeGuests":{"value":"true"},"gCal$sequence":{"value":0},"gCal$uid":{"value":"CSVConvert0cb9429bdc64a5a6c2052669ab368a40"}},{"id":{"$t":"http://www.google.com/calendar/feeds/admin%40test.org/public/full/_8d9lcgrfdpr6asjk6hh3gphjccpmaphg6opj0d316sq34cj570p3ic1j6grj4opgcoog"},"published":{"$t":"1900-01-01T12:00:00.000Z"},"updated":{"$t":"2013-08-20T11:13:33.000Z"},"category":[{"scheme":"http://schemas.google.com/g/2005#kind","term":

The above is a sample of one instance of such chunk of text, the real file could have multiple such chunks.

What i want to do is get the batch script to read the file and when it finds "title":{"$t":"Test Begins","type":"text"} i want Test Begins (in the example above but it could be any text in the real file) to be stored in a variable.

The script should continue reading the text file util it comes across ","startTime":"2014-01-16"}],"gd$transparency" here i want the date stored into a variable.

Now that we have the first pair of variables, i want them to be written to a text file in the following format:

[date] [text]

It keeps doing this until it gets to the end of the file being read.

I have been banging my head over this for a few days a i usually like to learn it without hassling people but i just cant get my head around this.

Your help will be much appreciated.

user3191135
  • 33
  • 1
  • 5

1 Answers1

1

Batch is not a good option for this problem because it generally cannot handle strings longer than 8191 characters, and your problem looks like it could easily exceed that limit.

A good option is some sort of regex processor. A Windows port of sed or awk would probably do well. There are free versions out there.

I have written REPL.BAT - a hybrid JScript/batch utility that performs a regex search and replace on stdin and writes the result to stdout. It is pure script that will run on any modern Windows machine from XP forward, without the need of any 3rd party executable. Full documentation is embedded within the script.

Assuming REPL.BAT is in your current directory, or better yet, somewhere within your PATH, the following should do the trick.

@echo off
setlocal
set "search=.*?\qtitle\q:{\q\$t\q:\q(.*?)\q,\qtype\q:\qtext\q}.*?\q,\qstartTime\q:\q(.*?)\q}],\qgd\$transparency\q"
type "input.txt" | repl "%search%" "$&\r\n" x | repl "%search%" "[$2][$1]" xa >"output.txt"

I ended up using REPL twice, first to insert a new line at the end of each chunk, and a second time to extract the values from each resultant line. It seems like there should be a one step solution, but I couldn't figure it out.


Update in response to comment

I've also written getTimeStamp.bat - a hybrid JScript/batch utility to compute and format date and time information. Assuming getTimeStamp.bat is in current directory or PATH, then the following will give your desired format.

@echo off
setlocal
set "search=.*?\qtitle\q:{\q\$t\q:\q(.*?)\q,\qtype\q:\qtext\q}.*?\q,\qstartTime\q:\q(.*?)\q}],\qgd\$transparency\q"
>"output.txt" (
  for /f "tokens=1,2 delims=[]" %%A in (
    'type "input.txt" ^| repl "%search%" "$&\r\n" x ^| repl "%search%" "[$1][$2]" xa'
  ) do (
    set "txt=%%A"
    set "dt=%%B"
    setlocal enableDelayedExpansion
    call getTimeStamp -d "'!dt:-=/!'" -f "{wkd} {dd} {mth}" -r dt
    echo [!dt!][!txt!]
    endlocal
  )
)

Final update in response to comment that has since been deleted

I added one additional REPL to strip out the initial "title":{"$t":"Unwanted Text","type":"text"}

@echo off
setlocal
set "skipSearch=\qtitle\q:\{\q\$t\q:\q.*?\q,\qtype\q:\qtext\q\}((\s|\S)*)"
set "search=.*?\qtitle\q:\{\q\$t\q:\q(.*?)\q,\qtype\q:\qtext\q\}.*?\q,\qstartTime\q:\q(.*?)\q}],\qgd\$transparency\q"
>"output.txt" (
  for /f "tokens=1,2 delims=[]" %%A in (
    'type "input.txt" ^| repl "%skipSearch%" "$1" mx ^| repl "%search%" "$&\r\n" x ^| repl "%search%" "[$1][$2]" xa'
  ) do (
    set "txt=%%A"
    set "dt=%%B"
    setlocal enableDelayedExpansion
    call getTimeStamp -d "'!dt:-=/!'" -f "{wkd} {dd} {mth}" -r dt
    echo [!dt!][!txt!]
    endlocal
  )
)

Another option, assuming "Calendar" is never a vaild value and should always be discarded, is to use the negative look ahead feature to prevent matching Calendar.

@echo off
setlocal
set "search=.*?\qtitle\q:\{\q\$t\q:\q(?!Calendar\q)(.*?)\q,\qtype\q:\qtext\q\}.*?\q,\qstartTime\q:\q(.*?)\q}],\qgd\$transparency\q"
>"output.txt" (
  for /f "tokens=1,2 delims=[]" %%A in (
    'type "input.txt" ^| repl "%search%" "$&\r\n" x ^| repl "%search%" "[$1][$2]" xa'
  ) do (
    set "txt=%%A"
    set "dt=%%B"
    setlocal enableDelayedExpansion
    call getTimeStamp -d "'!dt:-=/!'" -f "{wkd} {dd} {mth}" -r dt
    echo [!dt!][!txt!]
    endlocal
  )
)
Community
  • 1
  • 1
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • @debenham, you are a genius; works perfectly! wow!!! i will just play with it slightly to tweek it so the date is in a format that i don't want it in, ideally i want to change it to "Tue 14 Jan" rather than the current "2014-01-14" If i cant do it, i will post back. Once again, amazing help, thank you very much. – user3191135 Jan 14 '14 at 09:56
  • ok so the square brackets and order was a breeze once i looked at the script. so now only got the date issue to solve and also find some way for it to ignore the first occurrence of the required, which is same all the time so i don't need it. – user3191135 Jan 14 '14 at 10:05
  • @user3191135 - Oops, I missed the order issue. Fixed. See my updated answer for a simple date format solution using another hybrid script. Native batch also does not handle dates or times very well. I don't understand "first occurrence of the required" - perhaps that is a new question. – dbenham Jan 14 '14 at 12:21
  • thank you for your help, its now exactly as i wanted it. – user3191135 Jan 14 '14 at 15:52
  • @user3191135 - Added two options to skip the initial unwanted title. – dbenham Jan 14 '14 at 16:00