Selective file copy
Copy part of input records to an output file.
Show how file processing as known from PL/I or COBOL can be implemented in the
language of your choice.
Here, a file is not 'just' a sequence of bytes or lines but a sequence of recods (structured data). The structure is usually described by declarations contained in an INCLUDE file (PL/I) or COPY BOOK (COBOL).
The by name assignment is a little extra available in PL/I.
Data conversions may be necessary (as shown here for data element c.
Java
With a little help from my friens <lang java>import java.io.BufferedWriter; import java.io.FileWriter; import java.io.File; import java.io.IOException; import java.util.Scanner;
class CopysJ {
public static void main(String[] args) { String ddname_IN = "copys.in.txt"; String ddname_OUT = "copys.out.txt"; if (args.length >= 1) { ddname_IN = args[0].length() > 0 ? args[0] : ddname_IN; } if (args.length >= 2) { ddname_OUT = args[1].length() > 0 ? args[1] : ddname_OUT; }
File dd_IN = new File(ddname_IN); File dd_OUT = new File(ddname_OUT);
try ( Scanner scanner_IN = new Scanner(dd_IN); BufferedWriter writer_OUT = new BufferedWriter(new FileWriter(dd_OUT)) ) { String a; String b; String c; String d; String c1; String x = "XXXXX"; String data_IN; String data_OUT; int ib;
while (scanner_IN.hasNextLine()) { data_IN = scanner_IN.nextLine(); ib = 0; a = data_IN.substring(ib, ib += 5); b = data_IN.substring(ib, ib += 5); c = data_IN.substring(ib, ib += 4); c1=Integer.toHexString(new Byte((c.getBytes())[0]).intValue()); if (c1.length()<2) { c1="0" + c1; } data_OUT = a + c1 + x; writer_OUT.write(data_OUT); writer_OUT.newLine(); System.out.println(data_IN); System.out.println(data_OUT); System.out.println(); } } catch (IOException ex) { ex.printStackTrace(); } return; }
}</lang>
NetRexx
with a little help from a friend <lang netrexx>/* NetRexx */ -- nrc -keepasjava -savelog copys options replace format comments java crossref symbols nobinary
parse arg ddname_IN ddname_OUT . do
if ddname_IN.length = 0 then ddname_IN = 'copys.in.txt' if ddname_OUT.length = 0 then ddname_OUT = 'copys.out.txt'
dd_IN = File(ddname_IN) dd_OUT = File(ddname_OUT) scanner_IN = Scanner(dd_IN) writer_OUT = BufferedWriter(FileWriter(dd_OUT))
x = 'XXXXX' loop while scanner_IN.hasNextLine() data_IN = scanner_IN.nextLine() parse data_IN a +5 . /* b */ +5 c +4 . /* d */ cc=c.left(1).c2x data_OUT = a || cc.right(2,0) || x writer_OUT.write(data_OUT) writer_OUT.newLine() end
catch ex = IOException
ex.printStackTrace()
finally
do if scanner_IN \= null then scanner_IN.close() if writer_OUT \= null then writer_OUT.close() catch ex = IOException ex.printStackTrace() end
end</lang>
ooRexx
<lang oorexx>/* REXX */ infile ="in.txt" outfile="out.txt"
s1=.copys~new(infile,outfile) loop i=1 to 5
s1~~input~~output
end s1~close -- close streams (files) 'type' outfile
- class copys
- attribute a
- attribute b
- attribute c
- attribute d
- method init -- constructor
expose instream outstream parse arg infile, outfile instream =.stream~new(infile)~~open outstream=.stream~new(outfile)~~open("replace")
- method input -- read an input line
expose instream a b c d parse value instream~linein with a +5 b +5 c +5 d +5
- method output -- write an output line
expose outstream a c outstream~lineout(a || c~c2x~left(2)'XXXXX')
- method close -- close files
expose instream outstream instream~close outstream~close</lang>
- Output:
AA 01XXXXX AAA 02XXXXX AAAA 03XXXXX AAAAA04XXXXX AAAAA05XXXXX
PL/I
<lang pli>*process source attributes xref or(!);
copys: Proc Options(Main); Dcl 1 s1 unal, 2 a Char(5), 2 b Char(5), 2 c Bin Fixed(31), 2 d Char(5); Dcl 1 s2, 2 a Char(5), 2 c Pic'99', 2 x Char(5) Init('XXXXX'); Dcl o1 Record Output; /* create a test file */ Dcl in Record Input; Dcl out Record Output; Do i=1 To 5; s1.a=repeat('A',i); s1.b=repeat('B',i); s1.c=i; s1.d=repeat('D',i); Write File(o1) From(s1); End; Close File(o1);
On Endfile(in) Goto eoj; Do i=1 By 1; /* copy parts of the test file */ Read File(in) Into(s1); s2=s1, by name; /* only fields a and c are copied */ Write File(out) From(s2); End; eoj: End;
</lang>
- Output:
AA 01XXXXX AAA 02XXXXX AAAA 03XXXXX AAAAA04XXXXX AAAAA05XXXXX
REXX
<lang rexx>in='in.txt' out='out.txt'; 'erase' out Do While lines(in)>0
l=linein(in) Parse Var l a +5 b +5 c +4 d +5 chex=c2x(c) cpic=left(chex,2) call lineout out,a||cpic||'XXXXX' End
Call lineout in Call lineout out 'type' out</lang>
- Output:
Using the test file produced by PL/I. The data conversion used for c is not very general!
AA 01XXXXX AAA 02XXXXX AAAA 03XXXXX AAAAA04XXXXX AAAAA05XXXXX