Operating System - OpenVMS
1827439 Members
5420 Online
109965 Solutions
New Discussion

Re: How to extract string from command output?

 
SOLVED
Go to solution
Andrew Yip
Advisor

How to extract string from command output?

Hi Gurus,

I'm using a OVMS v5.5 and i'm trying to extract a particular string and word from a command output, for example:
==============================================
$ mem dis /int
Programs in 68040 Main Memory

File name Id Type Status
--------- -- ---- ------
P2780232N111AC1.INT
2 sum3 used
P1TD703130K10A4.INT
1 sum3
LIANG.INT 6 sum3 used

Total 3 files 380928 bytes. 2409472 bytes free.
$
==============================================

Now, how do i extract the free bytes information from the above output. In unix scripting, i would usually use the grep function. Can anyone offer help? Thanks!

Best Regards,

Andrew
______________________________________________
36 REPLIES 36
Wim Van den Wyngaert
Honored Contributor

Re: How to extract string from command output?

Use this as an example.

$ define/us sys$output 'ct_workf'
$ show proc/mem
$ open/read x 'ct_workf'
$r30:
$ read/end=e30 x x_rcd
$ x_rcd=f$ed(x_rcd,"compress")
$ pos=f$loc("Free Space (bytes)",x_rcd)
$ if pos .ne. f$len(x_rcd)
$ then
$ cur=f$int(f$elem(4," ",x_rcd))
$ if cur .ne. prevcur then d "Current free space : ''cur'"
$ prevcur==cur
$ if cur .le. 5000 then say "''CUR' free bytes process dynamic memory"
$ endif
$ goto r30
$e30:
$ close x

Wim
Andrew Yip
Advisor

Re: How to extract string from command output?

Hi Wim,
Thanks for your post, but do you have a simplier explanation for your example? I don't understand it very well. I'm pretty new to OVMS. Thanks!
Hein van den Heuvel
Honored Contributor
Solution

Re: How to extract string from command output?

Hello Andrew, welcome to the OpenVMS group.

In Wim's example he solves a much similar problem, and leaves it up to you to translate to your exact needs. I encourage you to study it and learn. The main 'trick' he uses, is a classic DCL scripting technique of searching for a substring. This returns the string length if not found.

Here is a solution taylored to your case where i start by loooking for an element, splitting the line by spaces. Compare the f$elem(7," ",record) with $7 in AWK.
P1 is the name of a file (SYS$PIPE if needed,

$close/nolog file ! In case it was left open
$open file 'p1
$loop:
$read /end=not_found file record
$if f$elem(7," ",record).NES."bytes" THEN GOTO loop
$if f$elem(8," ",record).NES."free." THEN GOTO loop
$bytes = f$elem(6," ",record)
$SHOW SYMBOL bytes
$CLOSE file
$EXIT
$not_found:
$WRITE SYS$OUTPUT "line with free bytes not recognized"
$CLOSE file

Be sure to read the fine HELP LEXICAL and help in genral, and try to get a 'programming in DCL' book in print.


Now 5.5 is a terribly old VMS version. I don;t suppose there is any hope to upgrade that?
Can you get PERL for 5.5?
If so, the solution of course can become nuch more like Unix:

$ perl -ne "print $1 if /(\d+)\s+bytes free.$/" tmp.tmp



hth,

Hein.
Robert Gezelter
Honored Contributor

Re: How to extract string from command output?

Andrew,

Basically, the script that Wlm posted scans the output one line at a time, looking for the string "Free Space (bytes)", and then extracting the information from the line. The output is re-routed from the standard output device, by default the terminal, to a scratch file contained in the variable "ct-workf". The command SHOW MEMORY is used to generate the output information to parse.

The processing and analysis of the lines is done using DCL lexical functions. These are documented in the DCL Dictionary (the documentation for the recent releases in available in PDF and HTML versions on the OpenVMS www site at http://www.hp.com/go/opemvms; while some new functions, and options have been added since 5.5, the manual is still usable; the information is also available online by using the command HELP LEXICAL).

I also did a presentation on the basics of DCL scripting at the Fall 1995 DECUS Symposium, you can get the slides from that session via http://www.rlgsc.com/decus/usf95/index.html).

- Bob Gezelter, http://www.rlgsc.com
Daniel Fernandez Illan
Trusted Contributor

Re: How to extract string from command output?

Andrew

Other solution is use pipe and search commands.
For example:
PIPE SHO PROC/MEM | SEAR SYS$INPUT "Free Space"

Happy new year.
Saludos.
Daniel.
Jan van den Ende
Honored Contributor

Re: How to extract string from command output?

Daniel,

look at the original question: VMS V5.5

That does not yet support PIPE.

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Daniel Fernandez Illan
Trusted Contributor

Re: How to extract string from command output?

Sorry Jan
I am landing from my vacations (much beer and wine) and I am still slept.

Sorry.
Saludos.
Daniel.
Daniel Fernandez Illan
Trusted Contributor

Re: How to extract string from command output?

Other solution without use PIPE

$DEFINE SYS$OUTPUT MEMO.TXT
$SHO PROC/MEM
$DEASS SYS$OUTPUT
$SEAR MEMO.TXT "Free Space"
$DELE MEMO.TXT.*

Saludos.
Daniel.
Phil.Howell
Honored Contributor

Re: How to extract string from command output?

Before there was pipe, I used @tt (undocumented) to redirect output
for example

$@tt /out=out.txt
$mem dis /int
$exit
$search out.txt "bytes free" /out=line.txt

line.txt then contains the total line
you can open and read the file into a symbol
and then use f$locate and f$extract to get your integer.
Phil

Andrew Yip
Advisor

Re: How to extract string from command output?

Hello Hein,

Thanks a million for your explanation. I now understand how to extract the strings.

Basically, i can get an output from my command and perform a search followed by a f$element function to extract the string.

However, is there any command or method to extract by line number?

Let's say for example, i would like to extract only line 1 of textfile A and line 2 onwards of textfile B. Finally join them into a new textfile.

The way i see f$element is extracting strings by a seperator character or element.

Please kindly advice. Thank you!

Andrew
____________________________________________
Andrew Yip
Advisor

Re: How to extract string from command output?

Hi Phil,

What are the workings beneath the 'tt'?
I can't run this in script mode. I'll have to execute it manually to obtain the output.

Andrew
____________________________________________
Karl Rohwedder
Honored Contributor

Re: How to extract string from command output?

The @ starts the commandfile TT, which is a logical name pointing to your terminal, but it allows for the /OUPUT qualifier.

There is a freeware utility called EXTRACT which allows to extract selectable record from files, see http://vms.process.com/scripts/fileserv/fileserv_search.exe?package=extract&description=&author=&system=Either&language=All&RD=&RM=&RY=

regards kalle
Ian Miller.
Honored Contributor

Re: How to extract string from command output?

TT is a logical name refering to your terminal.
$ @TT:

Is running a script from your terminal.

/OUTPUT redefines SYS$OUTPUT

The following will redirect output for one command then return to normal.

$ DEFINE/USER SYS$OUTPUT FILE.LIS
$ somecommandhere
Then open the file
$ OPEN HANDLE FILE.LIS
read the lines
$ READ HANDLE LINE
and process them.
____________________
Purely Personal Opinion
Andrew Yip
Advisor

Re: How to extract string from command output?

Hi Kalle,

Does the extract utility helps me in extracting particular lines from a textfile?

I'm unable to d/l the zip file.
Karl Rohwedder
Honored Contributor

Re: How to extract string from command output?

It allows specification of start/end records, start/end columns and can edit the extracted records (like F$EDIT, but more).

Here are the Examples from HELP:

2 examples
!Display the last 10 lines of Login.Com on the terminal
$ EXTRACT/TAIL=10 Login.Com /IDENTIFY

!Look at the first few lines of all Fortran source files
$ EXTRACT/HEAD=5 *.For

!Copy Test.Txt to Test.Dat, converting text into upper case
! and removing excess blanks.
$ EXTRACT/EDIT=(UPCASE,COMPRESS) Test.Txt/OUTPUT=Test.Dat

!Extract all but the first 10 and last 10 records of Test.Dat
$ EXTRACT Test.Dat/RECORDS=(START=11,END=-11) /OUTPUT=Test.Mid

!Get specific columns out of several files
$ EXTRACT/COLUMNS=(1:10,18:19,25,41:*) Test.*,[...]*.Tmp


I've added the ZIP file

regards Kalle
Hein van den Heuvel
Honored Contributor

Re: How to extract string from command output?

>> However, is there any command or method to extract by line number?
>> Let's say for example, i would like to extract only line 1 of textfile A and line 2 onwards of textfile B. Finally join them into a new textfile.

Sure, same loop through file principle, but keep a running count... in general. However, in the case of 1 or 2, I would just read it.
Untested example below.

Sounds like you'd better get that 'Programming in DCL book' and check out some examples, on your system or here in the forum.

However, since you are new to VMS/DCL I would suggest to learn PERL and/or AWK for file/line/text manipulation. You'll be able to use the skill on multiple platforms

$close/nolog file ! In case it was left open
$open file file-1
$n=6
$i=0
$loop:
$1=1+1
$read /end=not_found file record
$if i.lt.n then goto loop
$
$write sys$output "record ''n' = record"

Your question

$close/nolog file ! In case it was left open
$open file file-1
$read /end=not_found file record_1
$close file
$open file file-1
$read /end=not_found file record_2
$read /end=not_found file record_2
$close file
$open/write file file-3
$write file record_1 + record_2
$close file


to read record 123 in perl:

perl -ne "print if ($.== 123)"


Hein.
Jan van den Ende
Honored Contributor

Re: How to extract string from command output?

Andrew,

another wat to generate output from a command procedure, say ABCD.COM

$ @ABCD/OUTPUT= [p1] [p2] ...

Remember to put /out BEFORE any params.

hth

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Andrew Yip
Advisor

Re: How to extract string from command output?

I had extracted the numbers (free space) from the command output and made some logical comparison between them.

============================================
$ IF (MAINfreebytes .LES. INTfilesize) .OR. (VSMfreebytes .LES. PATfilesize)
$ THEN GOTO ERROR34
$ ELSE write temp "Free space check OK."
$ ENDIF
============================================

MAIN Memory free space: 2790400 bytes
VSM Memory free space: 59935744 bytes
Program file size: 91136 bytes
Pattern files size: 14043136 bytes
Insufficient tester memory space!

But the result was incorrect! This is so strange! I even explicitly defined them to be of integer type.

E.g.
$ INTfilesize = f$integer(f$element(4," ",record))

Can anyone advice on what is wrong here?
Thanks!

Andrew
Andrew Yip
Advisor

Re: How to extract string from command output?

Sorry, i wasn't very clear in my previous post.

i was comparing the following:

$ IF (2790400 .LES. 91136) .AND. (59935744 .LES. 14043136)
$ THEN write sys$output "Insufficient tester memory space!"
$ ELSE write temp "Free space check OK."
$ ENDIF
============================================
Result: Insufficient tester memory space!

I was expecting to see "Free space check OK."

Duncan Morris
Honored Contributor

Re: How to extract string from command output?

Andrew, you are using the wrong operator for comparison

.LE. 4 Arithmetic less than or equal

.LES. 4 String less than or equal

Try replacing .LES. with .LE. when working with numbers.
Jan van den Ende
Honored Contributor

Re: How to extract string from command output?

Andrew,

On the risk of being superfluous, some more explicit explanation of Duncans answer:

If you compare the STRING 5 with 123456, then it compares the first character of both, if equal the next char, etc, until a difference is found. And since "5" is greater than "1", so the string "5" is considered greater than "12345".

Sorry if this was already clear.

Proost.

Have one on me.

jpe
Don't rust yours pelled jacker to fine doll missed aches.
Andrew Yip
Advisor

Re: How to extract string from command output?

Hello Duncan & Jan,

Oops! Thanks for spotting the mistake.
I now realized using the wrong operator.
It works now. =)

By the way, if i were to search a file for a particular string and the result is negative, how do i get the empty result or status or whatever which i can work on?

E.g.
$ search temp.txt ABC /output=line.txt
%SEARCH-I-NOMATCHES, no strings matched

I need the result to perform some work. However if the search result is positive, at least i have something to retrieve from the 'line.txt' file to perform some work.

Is there any work-around solution to this?
Please advice, anyone. Thanks a million!

Andrew
Jan van den Ende
Honored Contributor

Re: How to extract string from command output?

Andrew,

your easiest pathway to achieve that is to do any search that results in "no strings matched".
_DIRECTLY_ after that do a
$ show symbol $status
Pick up the result and paste it into your command file.
In your command file, if for some reason it is undesirable or impossible to IMMEDIATELY act upon $STATUS, then start by saving it in another symbol, and use that later on.
Take care, the value of $status actually is in STRING format, so you need the string comparison operators.

Success.

Proost.

Have one on me.

jpe



Don't rust yours pelled jacker to fine doll missed aches.
John Abbott_2
Esteemed Contributor

Re: How to extract string from command output?

Hi Andrew,

The search command still generates a file, an emtpy one. From Wim's first post of code, the first read will result in an end-of-file detection and therefore the code will jump to e30: label.

If you want to do something else you could check the $severity level returned from the search command:

For %SEARCH-I-NOMATCHES, no strings matched
$SEVERITY == "3"

for matches
$SEVERITY == "1",

so after the search command line you could add $ IF $SEVERITY .EQS. "3" THEN ...

If course $STATUS could also be used and checked. ($SEVERITY and $STATUS return information about the previous DCL command executed, ie their level of success and return code, try typing $ write sys$output f$message($status) after entering an invalid dcl command)

Also, you could add the qualifer /NOWARNINGS to the search command to hide the "%SEARCH-I-NOMATCHES, no strings matched" message from appearing.

Kind Regards
John.
Don't do what Donny Dont does