Best way to parse out string from output? Is this acceptable?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Best way to parse out string from output? Is this acceptable?

#1 Post by SIMMS7400 » 07 Jan 2021 19:20

Hi Folks -

I have a need to extract a certain string from an output. What I do is spool all output from my command into a variable and then parse that variable. THe output varies in row count, it's never the same. But, the string in which I need to extract always has "logfilename" in the line.

Here is my code:

Code: Select all

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET LF=^


::-- DO NOT REMOVE THE TWO EMPTY LINES ABOVE HERE --::
SET "CMD_OUTPUT="
SET "SEARCH=logFileName"
FOR /F "tokens=5 delims=/" %%A IN ('TYPE test.log ^| FINDSTR /RSIMC:"\%SEARCH%"') DO (
	FOR /F Tokens^=1^ Delims^=^" %%a IN ("%%~A") DO (
		IF DEFINED CMD_OUTPUT SET "CMD_OUTPUT=!CMD_OUTPUT!!LF!"
			SET "CMD_OUTPUT=!CMD_OUTPUT!%%a"
		)
)

echo %CMD_OUTPUT%
pause
And here is a sample output:

Code: Select all

2021/01/07 06:13:12:103 EST [DEBUG] HttpMethodBase - Adding Host request header
2021/01/07 06:13:12:110 EST [DEBUG] header - >> "Authorization: Basic ********************************************[\r][\n]"
2021/01/07 06:13:12:110 EST [DEBUG] header - >> "Accept-Language: en-US[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "content-type: application/json[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "X-EPM_FUNCTION: EPM Automate[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "X-EPM_ACTION: Run Data Rule[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "X-EPM_OBJECT: jobName=GPM_Actual,startPeriod=Jan-20,importMode=REPLACE,fileName=inbox/batches/openbatchml/R_GPM_Actual_Jan-20_Dec-20_RR1.csv,exportMode=STORE_DATA,endPeriod=Dec-20,jobType=DATARULE[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "User-Agent: Jakarta Commons-HttpClient/3.1[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "Host: domain.pbcs.us2.oraclecloud.com[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "Content-Length: 212[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] header - >> "[\r][\n]"
2021/01/07 06:13:12:111 EST [DEBUG] content - >> "{"jobName":"GPM_Actual","startPeriod":"Jan-20","importMode":"REPLACE","fileName":"inbox/batches/openbatchml/R_GPM_Actual_Jan-20_Dec-20_RR1.csv","exportMode":"STORE_DATA","endPeriod":"Dec-20","jobType":"DATARULE"}"
2021/01/07 06:13:12:465 EST [DEBUG] EntityEnclosingMethod - Request body sent
2021/01/07 06:13:15:237 EST [DEBUG] header - << "HTTP/1.1 200 OK[\r][\n]"
2021/01/07 06:13:15:237 EST [DEBUG] header - << "HTTP/1.1 200 OK[\r][\n]"
2021/01/07 06:13:15:240 EST [DEBUG] header - << "Date: Thu, 07 Jan 2021 11:13:12 GMT[\r][\n]"
2021/01/07 06:13:15:243 EST [DEBUG] header - << "Server: Oracle-Application-Server[\r][\n]"
2021/01/07 06:13:15:243 EST [DEBUG] header - << "P3P: X-CONTENT-TYPE-OPTIONS:nosniff[\r][\n]"
2021/01/07 06:13:15:243 EST [DEBUG] header - << "X-ORACLE-DMS-ECID: 005i4q6XYmf6yGFpR0T4id0002bV0000RI[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Vary: Accept-Encoding,User-Agent[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Set-Cookie: EPMJSESSIONID=11DcjO9GVJj_D4iSxc73CKwQ-wYlgtxpiISjBDhpF5CWrNB3i6BB!-380467034; path=/; HttpOnly;HttpOnly;Secure[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Set-Cookie: _WL_AUTHCOOKIE_EPMJSESSIONID=5zOdJI0osQPgG8eCfC.R; path=/; secure; HttpOnly;HttpOnly;Secure[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Transfer-Encoding: chunked[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Content-Type: application/json; charset=UTF-8[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Content-Language: en[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "Strict-Transport-Security: max-age=31536000 ; includeSubDomains[\r][\n]"
2021/01/07 06:13:15:246 EST [DEBUG] header - << "[\r][\n]"
2021/01/07 06:13:15:249 EST [DEBUG] CookieSpec - Unrecognized cookie attribute: name=HttpOnly, value=null
2021/01/07 06:13:15:249 EST [DEBUG] CookieSpec - Unrecognized cookie attribute: name=HttpOnly, value=null
2021/01/07 06:13:15:250 EST [DEBUG] HttpMethodBase - Cookie accepted: "EPMJSESSIONID=11DcjO9GVJj_D4iSxc73CKwQ-wYlgtxpiISjBDhpF5CWrNB3i6BB!-380467034"
2021/01/07 06:13:15:250 EST [DEBUG] CookieSpec - Unrecognized cookie attribute: name=HttpOnly, value=null
2021/01/07 06:13:15:250 EST [DEBUG] CookieSpec - Unrecognized cookie attribute: name=HttpOnly, value=null
2021/01/07 06:13:15:250 EST [DEBUG] HttpMethodBase - Cookie accepted: "_WL_AUTHCOOKIE_EPMJSESSIONID=5zOdJI0osQPgG8eCfC.R"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "1"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "4"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "a"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "[\r]"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "[\n]"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "{"executedBy":"name@client.com","jobStatus":"RUNNING","outputFileName":null,"processType":"COMM_LOAD_BALANCES","jobId":30585,"logFileName":"outbox/logs/GPM_30585.log","links":[{"rel":"self","href":"https://domain.pbcs.us2.oracle.com:443/aif/rest/V1/jobs/30585","action":"POST"}],"details":null,"status":-1}"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "[\r]"
2021/01/07 06:13:15:251 EST [DEBUG] content - << "[\n]"
2021/01/07 06:13:15:456 EST [DEBUG] content - << "0"
2021/01/07 06:13:15:456 EST [DEBUG] content - << "[\r]
My code works but wondering if there's a more efficient way? My code is extracting outbox/logs/GPM_30585.log

I will always need to extract the string, the only different being outbox/logs/*.log. Is there a way better to extract that? Thank you!
Last edited by Squashman on 07 Jan 2021 22:03, edited 2 times in total.
Reason: MOD EDIT: Code tags are better suited for Input, Output and Code examples.

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Best way to parse out string from output? Is this acceptable?

#2 Post by Compo » 07 Jan 2021 20:25

You should provide more information about your posted file content. Is what has been rendered on this site, an accurate layout of your actual file content? The reason I ask is that your file appears to wrap lines, certainly on normal size screens, is that true? Whilst, I'm fairly sure that the files do not in actuality wrap, my thought is that, if this was the case, we couldn't say with absolute certainty, that there will always be a line containing the string logFileName? It could be possible that one line reads, logFi, and the next reading leName. Of course even worse would be,log, and FileName, or possibly even logFile, and Name, as those terms used alone could match on other lines too! I suppose the point I'm trying to make, is that without your clarification solutions may be better designed by reading the entire file as a single string, like its raw state, removing any carriage returns and/or linefeeds, then isolate the substring you need.

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: Best way to parse out string from output? Is this acceptable?

#3 Post by SIMMS7400 » 08 Jan 2021 03:10

Compo - thanks for the reply and great question. The lines are not wrapped. It outputs to a file and I can confirm with 100% certainty lines are not wrapped.

Thank you!

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Best way to parse out string from output? Is this acceptable?

#4 Post by Aacini » 08 Jan 2021 23:36

Your description of the problem is confusing/incomplete...

In first place, your code does not extract outbox/logs/GPM_30585.log as you said, but just GPM_30585.log
Executing a pipe to a FINDSTR command is much less efficient than directly giving the filename as parameter of FINDSTR.
In FINDSTR command:
  • /R switch is the opposite of /C, so you should include just one. In this case should be /C, but:
  • /C switch is useless if the search string have not spaces.
  • /S switch is useless without a file name.
  • /M switch is useless without a wild-card.
  • /I switch is not needed if you know the case of the search string.
You have not explained that you assumed that the "logFileName" line includes a date with two slashes and that the data you want is placed after another two slashes. If this is true, then your method to extract the data should always work correctly. However, if such a line format may change (you did not explained this point), then the method will eventually fail...
Anyway, your code does a lot of unnecessary management. This shorter code do the same:

Code: Select all

@ECHO OFF
SETLOCAL

SET "SEARCH=logFileName"
FOR /F "tokens=5 delims=/" %%A IN ('FINDSTR "%SEARCH%" test.txt') DO (
	FOR /F Delims^=^" %%a IN ("%%~A") DO SET "CMD_OUTPUT=%%a"
)

echo %CMD_OUTPUT%
pause
Antonio

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: Best way to parse out string from output? Is this acceptable?

#5 Post by SIMMS7400 » 09 Jan 2021 04:06

HI Antonio -

Thank you so much! So for the most part, there should always b e those two conditions (the two slashes for the date at the beginning as well as the two slashes just before the <name_XXXX>.log. However, to ensure it's dynamic, is there a way to extract the string based on the other string called "logfilename"? That word will ALWAYS immediately proceed the "/outbox/logs/<name_XXXX.log>

Compo
Posts: 600
Joined: 21 Mar 2014 08:50

Re: Best way to parse out string from output? Is this acceptable?

#6 Post by Compo » 09 Jan 2021 11:23

As an alternative, you could use the comma delimiter, which would mean that files which are at different levels in the tree are still returned. This version uses the comma, and find instead of findstr, which IMO is not required for this type of search string.

Code: Select all

@Echo Off & SetLocal EnableExtensions
Set "Source=test.log"
Set "Search=logFileName"
Set "Result="
If Exist "%Source%" For /F Delims^= %%G In (
	'%SystemRoot%\System32\find.exe "%Search%" 0^< "%Source%"'
) Do (Set "}=%%G" & SetLocal EnableDelayedExpansion
	For /F "UseBackQ Delims=," %%H In ('!}:*%Search%":=!'
	) Do EndLocal & Set "Result=%%~nxH")
If Defined Result Echo %Result%
Pause
If you wanted the path with the filename, just change %%~nxH to %%~H. BTW, the initially matched line, would still be available as %}%. too.

SIMMS7400
Posts: 546
Joined: 07 Jan 2016 07:47

Re: Best way to parse out string from output? Is this acceptable?

#7 Post by SIMMS7400 » 12 Jan 2021 18:03

Compo -

This works like a charm! Will do some more testing but so far so good, Thank you so much!!!

Post Reply