Operating System - OpenVMS
1823113 Members
3371 Online
109646 Solutions
New Discussion юеВ

Inserting a carriage return into file

 
Jim Frame_1
New Member

Inserting a carriage return into file

I regularly recieve a file on an openVMS system that is made up of multiple records, with each record having multiple segments. Attached is an example. I have a new line after each segment, but no end of record terminator. Each record begins with a MSH segment and ends with a CD3 segment. I want to create a script that I can run to insert a carriage return before each "MSH" combination. I have a global search and replace procedure which works well for strings. I am attaching a version of the script which is setup to replace a "~" with an "*". I have tested it by placing this script in a tpu file in the root directory and then moving to a directory with a test file. I run the script by entering this:
$edit/tpu/command=sys$login:gsr.tpu
I have been trying to modify this procedure to search for the new line MSH combination and replace it with a MSH but, I have not been able to do it. I am hoping that someone on this site will be able to point me in the right direction. Thanks in advance for any assistance you can offer me.



15 REPLIES 15
Jim Frame_1
New Member

Re: Inserting a carriage return into file

Me again. Here is the script. I could only attach one document to the posting.
Antoniov.
Honored Contributor

Re: Inserting a carriage return into file

Jim,
welcome to VMS forum.

I'm not an TPU expert but if I remember you can:
- Edit file with TPU
- Enter in command mode with PF4
- User REPL
- Old string: you can type MSH
- New String: Press Ctrl + V for quote, press RETURN key and MSH again
This should work.

Antonio Vigliotti
Antonio Maria Vigliotti
Antoniov.
Honored Contributor

Re: Inserting a carriage return into file

Again,
in HELP QUOTE there is your answer:
o To insert a special character from within an EVE initialization file
(such as in batch editing), use the TPU command and the EVE$INSERT_TEXT
procedure. For example, the following command line inserts an escape
character:

TPU EVE$INSERT_TEXT (ASCII (27));

Antonio Vigliotti
Antonio Maria Vigliotti
Dale A. Marcy
Trusted Contributor

Re: Inserting a carriage return into file

Jim,

Antonio is correct. However, be careful with the PF4. It can be the "DO" key depending on several factors, but it can also be the delete line key. You should be able to take Antonio's advice and apply it to your script file changing the ~ with MSH and the * with VV@MSH.

Hope this helps.
Bojan Nemec
Honored Contributor

Re: Inserting a carriage return into file

Jim,

Tell me if I am correct. You have a file which in dump looks like this:
MSH||MSH||MSH

And you want to get each MSH in one record.
Maybe this command will help you (try it on a copy of the file!):

$ SET FILE filename /ATTR=(RFM:STMLF)

If this does not help, can you attach a dump and DIR/FULL of the file.

Bojan
Hein van den Heuvel
Honored Contributor

Re: Inserting a carriage return into file


Jim,

What do you mean with ?
At first I though it was a NULL byte, but looking at the file it appears to be a LINEFEED (%x0A) so perhaps 'New-Line'?

I downloaded your attachment to my PC,
Then FTP'ed in BINARY mode, and I see a relatively neat file with LF seperators.

Using SET FILE/ATTR=RFM=STMLF it turns into a more or less normal VMS file, but with each segment in an RMS record.

I can then readily make a single RMS record with all the segments using the following perl one-liner:

perl -e "while(<>){chop; if (/^MSH/ && $rec){print ""$rec\n"";$rec=""""}$rec.=$_} print ""$rec\n""" x.tmp > xx.tm
p

In a perl script that would be:
-----------------tmp.p---------------
while (<>) {
chop;
if (/^MSH/ && $rec) {
print "$rec\n";
$rec="";
}
$rec.=$_;
}
print "$rec\n"
-----------------------
perl tmp.p x.tmp > xx.tmp

Both produce 6 record files.
Each record starting with MSH and ending in (some multiple) CD3 segments.

fwiw,
Hein.



Jim Frame_1
New Member

Re: Inserting a carriage return into file

Wow.... Great response on this forum and thanks for the welcome.

In answer to Bojan's question, you are nearly correct. I have a after each segment. Several segments to a record. So it would look like this:

MSH|||MFI|||CD3|||MSH||| and so on. In other words, my interface has no way to parse the inbound file into the individual records and the same terminator is used between all the segments with nothing as an end or record terminator. I am trying to add the in front of each MSH (except the first one) as the end of record terminator for the previous record in this batch file. Let me catch up on all the suggestions (after a meeting) and then I will attach the requested information. Thanks again all for the timely responses.
Doug Phillips
Trusted Contributor

Re: Inserting a carriage return into file

>>
my interface has no way to parse the inbound file into the individual records and the same terminator is used between all the segments with nothing as an end or record terminator.
<<

This looks like an EDI file, and it looks perfectly fine on the VMS side after telling RMS what it really is:

$SET FILE/ATTR=RFM=STMLF ! as Hein has said.

I'm surprised that an unchangeable "interface" would require segment terminators and terminating the last segment of a record set. Doesn't sound right.

What is your interface? Normally, rather than try to change the file, it's better to make your code process the file.

Each "segment" is an RMS record. Each is prefixed with a segment identifier. A set of segments make a record set.

In this case, MSH is the beginning of each record set and encountering the next MSH segment identifier or the end-of-file should trigger your end-of-record-set routine. Then either loop back to process the MSH, or finish up the end-of-job.

Forget about the "paper control" characters. Set the file's attributes correctly and you won't even see them. Let RMS do its job.
Jim Frame_1
New Member

Re: Inserting a carriage return into file

I will start at the top. I have tried to use Antonio's advice, but it seems to be geared toward manually modifing the file. I am attempting to automate this with the scripting. Dale applied Antionio's thinking to my scripting, however I can not get this to work. I am getting this:

***Error symbol replaced by "-"*** when I run the script.

Bojan's idea would work if each segment was a record, but that is not the case. I am attaching the dir/full and dump of the testfile.

Hein's idea looks promising, but I don't know what to do with perl. I tried entering the one liner and the perl command wasn't recognised. Could you tell me how to use this on VMS?

Finally to Doug, this is HL7 (health level 7) and in our system a carriage return, line feed is used to seperate records in a batch file. I need to modify the file.


Thanks to all for the replies, I really appreciate the help. Please keep them coming.
Bojan Nemec
Honored Contributor

Re: Inserting a carriage return into file

Jim,

Ok the file is an stream_lf file. You can concatenate the records using DCL:

$ open/write outf ""
$ open/read inf ""
$ rec=""
$l:
$ read inf inrec/end=end
$ if f$extract(0,3,inrec).eqs."MSH".and.rec.nes.""
$ then
$ write outf rec
$ rec = inrec
$ else
$ rec = rec + inrec
$ endif
$ goto l
$end:
$ write outf rec
$ close inf
$ close outf

if you need linefeeds between subrecords (MSI,DC3...) add this line at the begining:
$ lf[0,8]=10
and replace the line
$ rec = rec + inrec
to
$ rec = rec + lf + inrec

Now you have a file which has each record starting with MSH and the rest. If you need a stream file (records terminated with ) you can replace the first open with:

$ create/fdl=sys$input
RECORD
FORMAT STREAM
$ open/append outf ""

This will create a stream file and each record will be terminated with .

Bojan
Doug Phillips
Trusted Contributor

Re: Inserting a carriage return into file

Jim,

From what little bit I once knew about Cerner stuff, the records were logically defined by the segment prefixes. The lines (segments) could have whatever line terminators the OS used -- for *nix, for M$ -- but the software didn't care. With RMS all you do is set the file's attribute so that it matches the data and it works.

It looks like you did the $set file/attr, so did you test it the way it is? Did it fail?
Hein van den Heuvel
Honored Contributor

Re: Inserting a carriage return into file

Based on Doug's comments, and the dump, I would expect you are all set and need no processing. If you are concerned about how it prints/shows then you could try:
$ set file/attr=rat=cr file
Still, that should make no difference for an application. Verify with $DUMP/RECOR[=count=10]

You could make it more of a VMS file using:
$CONV/FDL=NL: old new
That would make it variable length record form, but again it should not make much difference.

Along the same lines, if you just need CR-LF, but can leave the segments then:
$CONVERT/FDL=SYS$INPUT old new
RECORD; FORMAT STREAM
$

My perl scripts would glue the segments together, but does need perl installed.
Sounds like you do not have perl for now.

Bojan's DCL script does exactly the same as the perl script. It may need a WRITE/SYMBOL OUTF REC instead of plain write if the record gets too long.


Good luck,
Hein.
Antoniov.
Honored Contributor

Re: Inserting a carriage return into file

Jim,
as other Gurus posted, you can read this file without any modification.
If yes, you can simply see file with
$ TYPE
and see every segment in a line because LF (code hex 0A) is line delimiter.
In the same way, you can read file as Bojan suggested you.
So the real question is: what do you want to do with this file?

Antonio Vigliotti
Antonio Maria Vigliotti
John Yu_1
Valued Contributor

Re: Inserting a carriage return into file

you can also try convert/fdl to automate this
Artificial intelligence is rarely a match for natural stupidity.
Dale A. Marcy
Trusted Contributor

Re: Inserting a carriage return into file

Does your resulting script look like the attached? I have not tested this, but I still think it should work. One thing I am not clear of on this is whether MSH is actual ascii characters in the file or a pnemonic for a control character. If actual ascii characters the attached script should work. If pnemonic, then the MSH would have to be changed to insert the value of the control character.