program rb(input, output); (* remove blanks from ends of lines, and trailing blank lines from a file Dr. Thomas D. Schneider National Cancer Institute Laboratory of Experimental and Computational Biology Frederick, Maryland 21702-1201 toms@ncifcrf.gov permanent email: toms@alum.mit.edu http://www.lecb.ncifcrf.gov/~toms/ module libraries: delman, prgmods *) const (* begin module version *) version = 1.03; (* of rb.p 2002 Nov 19 2002 Nov 19, 1.03: remove tabs too! 2000 Dec 4, 1.02: use stdin 2000 Mar 31, 1.01: fix synopsis 2000 Jan 10, 1.00: origin from rembla *) (* end module version *) (* begin module describe.rb *) (* name rb: remove blanks from ends of lines in a file synopsis rb(input: stdin, output: out) files input: a text file output: a copy of fin with trailing blanks removed from all lines, any blank lines at the end of the file will also be removed. Tabs are counted as blanks. description Blanks can creep onto the end of lines in a file without one knowing it, either by the computer system, from transportation or an editor. This program removes those blanks, so that less storage is needed for the file. Some programs require that there be no blank lines in the file, yet transportation can generate blank lines at the end of the file. This program will remove such lines. The original rembla program uses fin and fout files. This rb version uses input and output to allow it to be used in Unix pipes: rb < myinputfile > my outputfile or ... | rb | sort | ... see also {Description of what stdin means: } shell.p {file version:} rembla.p author Thomas D. Schneider bugs none known *) (* end module describe.rb *) { (* begin module plural *) procedure plural(var thefile: text; number: integer); (* if the number is not 1, return an s *) begin (* plural *) if number <> 1 then write(thefile,'s') end; (* plural *) (* end module plural *) } procedure themain(var fin, fout: text); (* the main procedure of the program *) const tab = ' '; (* the tab character *) var blankchars, (* the number of blank characters currently counted *) tabchars, (* the number of tab characters currently counted *) blanklines, (* the number of blank lines currently counted *) totalblankchars, (* the actual number of blanks removed *) index: (* a counter for blanks and lines *) integer; wasblank: boolean; (* was a line blank? *) begin (* rb *) { writeln(output,' rb ',version:4:2); } blanklines := 0; totalblankchars := 0; (* the mechanism of the program is very simple: copy fin to fout. when blanks appear, do not write them to fout, but keep track of how many there are. if another character appears on the line, then first write any blanks out before the character. if no other characters appear on the line, we forget to write out the blanks... the same principle is applied to lines, so that extra blank lines at the end of the file will not be written out. *) while not eof(fin) do begin blankchars := 0; tabchars := 0; wasblank := true; (* copy a line *) while not eoln(fin) do begin if fin^ = ' ' then blankchars := succ(blankchars) else if fin^ = tab then tabchars := succ(tabchars) else begin if blanklines <> 0 then begin for index := 1 to blanklines do writeln(fout); blanklines := 0 (* reset *) end; if blankchars <> 0 then begin for index := 1 to blankchars do write(fout,' '); blankchars := 0 (* reset *) end; if tabchars <> 0 then begin for index := 1 to tabchars do write(fout,' '); tabchars := 0 (* reset *) end; write(fout, fin^); wasblank := false end; get(fin) end; (* count the ones left over *) totalblankchars := totalblankchars + blankchars; if wasblank then blanklines := succ(blanklines) else writeln(fout); (* the actual end of that line *) readln(fin) end; { write(output,' ',totalblankchars:1,' blank'); plural(output, totalblankchars); writeln(output,' removed'); write(output,' ',blanklines:1,' blank line'); plural(output, blanklines); writeln(output,' at the end removed') } end; begin themain(input, output); end. (* rb *)