Reverse the order of lines in a text file while preserving the contents of each line: Difference between revisions

From Rosetta Code
Content added Content deleted
m (changed (draft) task requirements as it stated previously, one could interpret the wording as that the original file was to be overwritten with the lines/records in reverse order/)
m (→‎{{header|Wren}}: Minor tidy)
 
(42 intermediate revisions by 25 users not shown)
Line 2: Line 2:


;Task:
;Task:
:*   Read an an entire (input) file   (into memory or buffers).
:*   Read an entire (input) file   (into memory or buffers).
:*   Display the lines/records of the entire file in reverse order.
:*   Display the lines/records of the entire file in reverse order.
:*   Show the results here, on this page.
:*   Show the results here, on this page.
Line 19: Line 19:
Also, don't include the rightmost informative comments   (◄■■■■■■),   as they are not meant to be part of the file.
Also, don't include the rightmost informative comments   (◄■■■■■■),   as they are not meant to be part of the file.
<br><br>
<br><br>

Reference: [https://linuxhint.com/bash_tac_command/ Bash tac command]

=={{header|11l}}==
{{trans|Python}}

<syntaxhighlight lang="11l">:start:
V fileData = File(:argv[1]).read().split("\n")

L(line) reversed(fileData)
print(line)</syntaxhighlight>

=={{header|Action!}}==
In the following solution the input file [https://gitlab.com/amarok8bit/action-rosetta-code/-/blob/master/source/rodgers.txt rodgers.txt] is loaded from H6 drive. Altirra emulator automatically converts CR/LF character from ASCII into 155 character in ATASCII charset used by Atari 8-bit computer when one from H6-H10 hard drive under DOS 2.5 is used.
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
DEFINE BUFFERSIZE="1000"
BYTE ARRAY buffer(BUFFERSIZE)
PTR ARRAY lines(100)
BYTE count=[0]

PROC AddLine(CHAR ARRAY line)
CHAR ARRAY dst

IF count=0 THEN
dst=buffer
ELSE
dst=lines(count-1)
dst==+dst(0)+1
FI
IF dst+line(0)+1>=buffer+BUFFERSIZE THEN
Print("End of memory!")
Break()
FI
SCopy(dst,line)
lines(count)=dst
count==+1
RETURN

PROC ReadFile(CHAR ARRAY fname)
CHAR ARRAY line(255)
BYTE dev=[1]

Close(dev)
Open(dev,fname,4)
WHILE Eof(dev)=0
DO
InputSD(dev,line)
AddLine(line)
OD
Close(dev)
RETURN

PROC Main()
CHAR ARRAY s
BYTE i,LMARGIN=$52,oldLMARGIN

oldLMARGIN=LMARGIN
LMARGIN=0 ;remove left margin on the screen
Put(125) PutE() ;clear the screen

ReadFile("H6:RODGERS.TXT")
FOR i=0 TO count-1
DO
s=lines(count-1-i)
PrintE(s)
OD

LMARGIN=oldLMARGIN ;restore left margin on the screen
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Reverse_the_order_of_lines_in_a_text_file_while_preserving_the_contents_of_each_line.png Screenshot from Atari 8-bit computer]
<pre>
--- Will Rodger

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_Io;
with Ada.Containers.Indefinite_Vectors;
with Ada.Command_Line;

procedure Reverse_Lines_In_File is

subtype Line_Number is Natural;

package Line_Vectors
is new Ada.Containers.Indefinite_Vectors
(Index_Type => Line_Number,
Element_Type => String);

use Line_Vectors,
Ada.Text_Io,
Ada.Command_Line;

File : File_Type;
Buffer : Vector;
begin
if Argument_Count = 1 then
Open (File, In_File, Argument (1));
Set_Input (File);
end if;

while not End_Of_File loop
Buffer.Prepend (Get_Line);
end loop;

if Is_Open (File) then
Close (File);
end if;

for Line of Buffer loop
Put_Line (Line);
end loop;

end Reverse_Lines_In_File;</syntaxhighlight>

=={{header|ALGOL W}}==
<syntaxhighlight lang="algolw">begin % reverse the order of the lines read from standard input %
% record to hold a line and link to the next %
record LinkedLine ( string(256) text; reference(LinkedLine) next );
string(256) line;
reference(LinkedLine) lines;
% allow the program to continue after reaching end-of-file %
ENDFILE := EXCEPTION( false, 1, 0, false, "EOF" );
% handle the input %
lines := null;
readcard( line );
while not XCPNOTED(ENDFILE) do begin
lines := LinkedLine( line, lines );
readcard( line )
end while_not_eof ;
% show the lines in reverse order %
while lines not = null do begin
integer len;
% find the length of the line with trailing spaces removed %
len := 255;
line := text(lines);
while len > 0 and line( len // 1 ) = " " do len := len - 1;
% print the line, note Algol W does not allow variable length substrings %
write( s_w := 0, line( 0 // 1 ) );
for cPos := 1 until len do writeon( s_w := 0, line( cPos // 1 ) );
lines := next(lines)
end while_lines_ne_null
end.</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f REVERSE_THE_ORDER_OF_LINES_IN_A_TEXT_FILE_WHILE_PRESERVING_THE_CONTENTS_OF_EACH_LINE.AWK filename
{ arr[NR] = $0 }
END {
for (i=NR; i>=1; i--) {
printf("%s\n",arr[i])
}
exit(0)
}
</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>


=={{header|BASIC256}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">source = freefile
open (source, "text.txt")
textEnt$ = ""
dim textSal$(size(source)*8)
linea = 0

while not eof(source)
textEnt$ = readline(source)
linea += 1
textSal$[linea] = textEnt$
end while

for n = size(source) to 1 step -1
print textSal$[n];
next n
close source
end</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>


=={{header|F_Sharp|F#}}==
<syntaxhighlight lang="fsharp">
// Reverse the order of lines in a text file while preserving the contents of each line. Nigel Galloway: August 9th., 2022
seq{use n=System.IO.File.OpenText("wr.txt") in while not n.EndOfStream do yield n.ReadLine()}|>Seq.rev|>Seq.iter(printfn "%s")
</syntaxhighlight>
{{out}}
<pre>
-- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>
=={{header|Factor}}==
{{works with|Factor|0.99 2021-06-02}}
<syntaxhighlight lang="factor">USING: io io.encodings.utf8 io.files sequences ;

"rodgers.txt" utf8 file-lines <reversed> [ print ] each</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|Delphi}}==
''See maybe [[#Free Pascal|Free Pascal]]''

=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">open "text.txt" for input as #1
dim as string textEnt, textSal()
dim as integer n, linea = 0

do while not eof(1)
line input #1, textEnt
linea += 1
redim preserve textSal(linea)
textSal(linea) = textEnt
loop

for n = ubound(textSal) to 1 step -1
print textSal(n)
next n
close #1
sleep</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|Free Pascal}}==
<syntaxhighlight lang="pascal">program TAC;
{$IFDEF FPC}
{$MODE DELPHI}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
sysutils, classes;
var
Sl:TStringList;
i,j : nativeInt;
begin
Sl := TStringList.Create;
Sl.Loadfromfile('Rodgers.txt');
i := 0;
j := Sl.Count-1;
While i<j do
Begin
Sl.Exchange(i,j);
inc(i);
dec(j);
end;
writeln(Sl.text);
end.</syntaxhighlight>{{out}}
<pre> --- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of</pre>


=={{header|Go}}==
=={{header|Go}}==
{{trans|Wren}}
{{trans|Wren}}
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 64: Line 351:
}
}
fmt.Println(string(b))
fmt.Println(string(b))
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 73: Line 360:
saying 'Nice Doggy'
saying 'Nice Doggy'
"Diplomacy is the art of
"Diplomacy is the art of
</pre>

=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import qualified Data.Text as T
import qualified Data.Text.IO as TIO

main :: IO ()
main = TIO.interact $ T.unlines . reverse . T.lines</syntaxhighlight>
{{out}}
<pre>
$ tac < tac.in
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|J}}==

<syntaxhighlight lang="j"> ;|.<;.2 text
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of</syntaxhighlight>

where
<syntaxhighlight lang="j">text=: {{)n
"Diplomacy is the art of
saying 'Nice Doggy'
until you can find a rock."

--- Will Rodgers
}}</syntaxhighlight>

or <syntaxhighlight lang="j">text=: fread 'filename'</syntaxhighlight> if the text were stored in a file named <code>filename</code>.

=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
<syntaxhighlight lang="sh">
jq -nRr '[inputs] | reverse[]' input.txt
</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>
</pre>


=={{header|Julia}}==
=={{header|Julia}}==
The optional <pre>keep</pre> argument to <pre>readlines</pre> means to keep the newline char at the end of each line. The <pre>|></pre>
The optional <pre>keep</pre> argument to <pre>readlines</pre> means to keep the newline '\n' char or '\r\n' digraph at the end of each line. The <pre>|></pre>
symbolism is the pipe operator. and the <pre>.|></pre> symbolism means to pipe each line in the read array to print separately.
symbolism is the pipe operator. and the <pre>.|></pre> symbolism means to pipe each line in the read array to print separately.
<lang julia>readlines("diplomacyrodgers.txt", keep=true) |> reverse .|> print</lang>{{output}}
<syntaxhighlight lang="julia">readlines("diplomacyrodgers.txt", keep=true) |> reverse .|> print</syntaxhighlight>{{output}}
<pre>
<pre>
--- Will Rodgers
--- Will Rodgers
Line 94: Line 432:


– there is enough memory to process the file in memory i.e to store the input file as a string, the sequence of lines, the reverse sequence of lines and the output file as a string.
– there is enough memory to process the file in memory i.e to store the input file as a string, the sequence of lines, the reverse sequence of lines and the output file as a string.
<lang Nim>import algorithm, strutils
<syntaxhighlight lang="nim">import algorithm, strutils


proc reverseLines(infile, outfile: File) =
proc reverseLines(infile, outfile: File) =
Line 109: Line 447:
echo ">>>>> Output file:"
echo ">>>>> Output file:"
reverseLines(infile, stdout)
reverseLines(infile, stdout)
echo ">>>>>"</lang>
echo ">>>>>"</syntaxhighlight>


{{out}}
{{out}}
Line 128: Line 466:
"Diplomacy is the art of
"Diplomacy is the art of
>>>>></pre>
>>>>></pre>

=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let rec read_lines_reverse lst =
match read_line () with
| line -> read_lines_reverse (line :: lst)
| exception End_of_file -> lst

let () = read_lines_reverse [] |> List.iter print_endline</syntaxhighlight>
{{out}}
<pre>
$ ocaml tac.ml <file.txt
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|Pascal}}==
''See also [[#Delphi|Delphi]] and [[#Free Pascal|Free Pascal]]''<br/>
The following is an ISO-compliant <tt>program</tt>.
Some compilers, however, such as the FPC (Free Pascal Compiler) or Delphi, cannot handle files without file names.
<syntaxhighlight lang="pascal">program tac(input, output);

procedure reverse;
var
line: text;
begin
{ Open for (over-)writing. }
rewrite(line);
{ `EOLn` is shorthand for `EOLn(input)`. }
while not EOLn do
begin
{ `line^` and `input^` refer to buffer variables [their values]. }
line^ := input^;
{ Write buffer and advance writing position. }
put(line);
{ Advance reading cursor and obtain next value [if such exists]. }
get(input)
end;
{ Consume “newline” character in `input` }
readLn;
{ Likewise, `EOF` is shorthand for `EOF(input)`. }
if not EOF then
begin
reverse
end;
{ (Re‑)open for reading. }
reset(line);
while not EOLn(line) do
begin
output^ := line^;
put(output);
get(line)
end;
{ `writeLn` is shorthand for `writeLn(output)`. }
writeLn
end;

begin
reverse
end.</syntaxhighlight>
{{out}}
--- Will Rodgers
until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
Note, this <tt>program</tt> will append a “new line” character to the final line if it did not exist.


=={{header|Perl}}==
=={{header|Perl}}==
as one-liner ..
as one-liner ..
<lang perl>// 20210803 Perl programming solution
<syntaxhighlight lang="perl">// 20210803 Perl programming solution


< input.txt perl -e 'print reverse <>'</lang>
< input.txt perl -e 'print reverse <>'</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 142: Line 555:
"Diplomacy is the art of
"Diplomacy is the art of
</pre>
</pre>

=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
"Diplomacy is the art of
saying 'Nice Doggy'
until you can find a rock."
--- Will Rodgers"""</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rogers.txt"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rogers.txt"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"w"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">text</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rogers.txt"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">text</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\r\n"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">text</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)})</span>
<!--</syntaxhighlight>-->
Obviously you can test the file handling by running the above, then changing eg Diplomacy to Diplomaxy and re-running it, and checking it outputs the previously saved c rather than the replacement x.
{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|Python}}==
Interactive program which takes input from a file :
<syntaxhighlight lang="python">
#Aamrun, 4th October 2021

import sys

if len(sys.argv)!=2:
print("Usage : python " + sys.argv[0] + " <filename>")
exit()

dataFile = open(sys.argv[1],"r")

fileData = dataFile.read().split('\n')

dataFile.close()

[print(i) for i in fileData[::-1]]
</syntaxhighlight>
Input file :
<pre>
"Diplomacy is the art of
saying 'Nice Doggy'
until you can find a rock."
--- Will Rodgers
</pre>
Sample run and output:
{{out}}
<pre>

C:\My Projects\BGI>python rosetta7.py diplomaticQuote.txt
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of

C:\My Projects\BGI>
</pre>

=={{header|Quackery}}==

<syntaxhighlight lang="Quackery"> [ sharefile drop
[] swap
[ carriage over find split
dup $ "" != while
behead drop
unrot nested swap join
swap again ]
drop nested swap join
witheach [ echo$ cr ] ] is task ( $ --> )

$ "rosetta/input.txt" task</syntaxhighlight>

{{out}}

<pre> --- Will Rodgers
until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>

=={{header|R}}==
<syntaxhighlight lang="rsplus">text <- scan("Rodgers.txt", character(), sep = "\n")
print(text)
reversed <- rev(text)
print(reversed)
write(reversed, "SaveTheOutput.txt")</syntaxhighlight>
{{out}}
<pre>Read 5 items
[1] " \"Diplomacy is the art of"
[2] " saying 'Nice Doggy'"
[3] "until you can find a rock.\""
[4] " "
[5] " --- Will Rodgers"
[1] " --- Will Rodgers"
[2] " "
[3] "until you can find a rock.\""
[4] " saying 'Nice Doggy'"
[5] " \"Diplomacy is the art of" </pre>


=={{header|Raku}}==
=={{header|Raku}}==
Not going to bother testing with the task recommended file. It demonstrates nothing to do with file handling, record separators, memory conservation or anything useful. May as well just be "Reverse this list" for all the good it does.

===Lots of assumptions===
Simplest thing that could possibly satisfy the extremely vague task description and completely glossing over all of the questions raised on the discussion page.
Simplest thing that could possibly satisfy the extremely vague task description and completely glossing over all of the questions raised on the discussion page.


Line 152: Line 684:
* May hold entire file in memory.
* May hold entire file in memory.


<lang perl6>.put for reverse lines</lang>
<syntaxhighlight lang="raku" line>.put for reverse lines</syntaxhighlight>

===Few assumptions===
Processes a small (configurable) number of bytes at a time so file can be multi-terabyte and it will handle with ease. ''Does'' assume Latin 1 for reduced complexity.

No assumptions were made concerning line/record termination, full stop.

Run the following to generate nul.txt. (digits 1 through 6 repeated 8 times with double null as record separators):

raku -e'print join "\x00\x00", (1..6).map: * x 8' > nul.txt

<syntaxhighlight lang="raku" line>my $input-record-separator = "\x00\x00";

my $fh = open("nul.txt".IO, :r, :bin);
$fh.seek(0, SeekFromEnd); # start at the end of the file

my $bytes = 5 min $fh.tell - 1; # read in file 5 bytes at a time (or whatever)

$fh.seek(-$bytes, SeekFromCurrent);

my $buffer = $fh.read($bytes).decode('Latin1'); # assume Latin1 for reduced complexity

loop {
my $seek = ($fh.tell < $bytes * 2) ?? -$fh.tell !! -$bytes * 2;
$fh.seek($seek, SeekFromCurrent);
$buffer = $buffer R~ $fh.read((-$seek - $bytes) max 0).decode('Latin1');
if $buffer.contains: $input-record-separator {
my @rest;
($buffer, @rest) = $buffer.split: $input-record-separator;
.say for reverse @rest; # emit any full records that have been processed
}
last if $fh.tell < $bytes;
}

say $buffer; # emit any remaining record</syntaxhighlight>
{{out}}
<pre>66666666
55555555
44444444
33333333
22222222
11111111</pre>


=={{header|REXX}}==
=={{header|REXX}}==
=== version 1 ===
This will work for all REXXes, &nbsp; but it reads all the file's lines/records into memory (storage or buffers).

No assumptions were made concerning line/record termination, &nbsp; as REXX takes care of that.
No assumptions were made concerning line/record termination, &nbsp; as REXX takes care of that.
<lang rexx>/*REXX pgm reads a file, and displays the lines (records) of the file in reverse order. */
<syntaxhighlight lang="rexx">/*REXX pgm reads a file, and displays the lines (records) of the file in reverse order. */
parse arg iFID . /*obtain optional argument from the CL.*/
parse arg iFID . /*obtain optional argument from the CL.*/
if iFID=='' | iFID=="," then iFID='REVERSEF.TXT' /*Not specified? Then use the default.*/
if iFID=='' | iFID=="," then iFID='REVERSEF.TXT' /*Not specified? Then use the default.*/
call lineout iFid /*close file, good programming practice*/
call lineout iFID /*close file, good programming practice*/
do #=1 while lines(iFID)>0 /*read the file, one record at a time. */

do j=1 while lines(iFID)>0 /*read the file, one record at a time. */
@.#= linein(iFID) /*assign contents of a record to array.*/
@.j= linein(iFID) /*assign contents of a record to array.*/
end /*#*/
end /*j*/
recs= # - 1 /*# will be 1 more ('cause of DO loop)*/
recs= j - 1 /*J will be 1 more ('cause of DO loop)*/
do k=recs by -1 for recs /*process array (@.k) in reverse order.*/
do k=recs by -1 for recs /*process array (@.k) in reverse order.*/
say @.k /*display a record of the file ──► term*/
say @.k /*display a record of the file ──► term*/
end /*k*/
end /*k*/
call lineout iFid /*close file, good programming practice*/</lang>
call lineout iFID /*close file, good programming practice*/</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
Line 177: Line 752:
"Diplomacy is the art of
"Diplomacy is the art of
</pre>
</pre>

=== version 2 ===
This will work for all the following REXXes &nbsp; (and perhaps other REXXes as well):
::* &nbsp; Regina REXX
::* &nbsp; R4 REXX
::* &nbsp; ROO REXX
::* &nbsp; CMS REXX compiler
::* &nbsp; CMS OREXX
<syntaxhighlight lang="text">/*REXX pgm reads a file, and displays the lines (records) of the file in reverse order. */
parse arg iFID . /*obtain optional argument from the CL.*/
if iFID=='' | iFID=="," then iFID='REVERSEF.TXT' /*Not specified? Then use the default.*/
call lineout iFID /*close file, good programming practice*/
options nofast_lines_BIF_default /*an option just for Regina REXX. */
#= lines(iFID) /*#: the number of lines in the file. */
do j=# by -1 for # /*read file (backwards), from bot──►top*/
say linein(iFID, j) /*display record contents ──► terminal.*/
end /*j*/
call lineout iFID /*close file, good programming practice*/</syntaxhighlight>
{{out|output|text=&nbsp; is identical to the 1<sup>st</sup> REXX version.}} <br><br>


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
load "stdlib.ring"
load "stdlib.ring"
see "working..." + nl
see "working..." + nl
Line 208: Line 802:


see nl + "done..." + nl
see nl + "done..." + nl
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 226: Line 820:
done...
done...
</pre>
</pre>

=={{header|Ruby}}==
<syntaxhighlight lang="ruby">puts File.readlines("diplomacy.txt").reverse</syntaxhighlight>
{{out}}
<pre> --- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>
=={{header|sed}}==
<syntaxhighlight lang="sed">1!G
h
$!d</syntaxhighlight>
{{out}}
<pre>
$ sed -f tac.sed file.txt
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of

</pre>

=={{header|UNIX Shell}}==
<syntaxhighlight lang="bash">tac rodgers.txt</syntaxhighlight>
{{out}}
<pre>
--- Will Rodgers
until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of
</pre>
Notice that '''tac''' is '''cat''' in reverse order.


=={{header|Wren}}==
=={{header|Wren}}==
{{libheader|Wren-ioutil}}
{{libheader|Wren-ioutil}}
<lang ecmascript>import "/ioutil" for File, FileUtil
<syntaxhighlight lang="wren">import "./ioutil" for File, FileUtil


var fileName1 = "rodgers.txt"
var fileName1 = "rodgers.txt"
Line 245: Line 875:
}
}
// print contents of output file to terminal
// print contents of output file to terminal
System.print(File.read(fileName2))</lang>
System.print(File.read(fileName2))</syntaxhighlight>


{{out}}
{{out}}
Line 254: Line 884:
saying 'Nice Doggy'
saying 'Nice Doggy'
"Diplomacy is the art of
"Diplomacy is the art of
</pre>

=={{header|XPL0}}==
Usage: rev <will.txt
<syntaxhighlight lang="xpl0">char Array(1000, 1000); \(tacky)
int Line, Char, I;
def LF=$0A, EOF=$1A;
[Line:= 0;
repeat I:= 0;
repeat Char:= ChIn(1);
Array(Line, I):= Char; I:= I+1;
until Char = LF or Char = EOF;
Line:= Line+1;
until Char = EOF;
for Line:= Line-2 downto 0 do
[I:= 0;
repeat Char:= Array(Line, I); I:= I+1;
ChOut(0, Char);
until Char = LF;
];
]</syntaxhighlight>

{{out}}
<pre>
--- Will Rodgers

until you can find a rock."
saying 'Nice Doggy'
"Diplomacy is the art of

</pre>
</pre>

Latest revision as of 12:28, 2 February 2024

Reverse the order of lines in a text file while preserving the contents of each line is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task
  •   Read an entire (input) file   (into memory or buffers).
  •   Display the lines/records of the entire file in reverse order.
  •   Show the results here, on this page.


For the input file, use the following five lines (records):

 "Diplomacy is the art of                                    ◄■■■■■■ starts in column 3.
   saying  'Nice Doggy'                                      ◄■■■■■■ starts in column 5,
until you can find a rock."                                  ◄■■■■■■ starts in column 2,
                                                             ◄■■■■■■ (a blank line),
                            --- Will Rodgers                 ◄■■■■■■ starts in column 30.


You can (or may) assume there are no superfluous trailing blanks,   and that line four has one blank.

Also, don't include the rightmost informative comments   (◄■■■■■■),   as they are not meant to be part of the file.

Reference: Bash tac command

11l

Translation of: Python
:start:
V fileData = File(:argv[1]).read().split("\n")

L(line) reversed(fileData)
   print(line)

Action!

In the following solution the input file rodgers.txt is loaded from H6 drive. Altirra emulator automatically converts CR/LF character from ASCII into 155 character in ATASCII charset used by Atari 8-bit computer when one from H6-H10 hard drive under DOS 2.5 is used.

DEFINE PTR="CARD"
DEFINE BUFFERSIZE="1000"
BYTE ARRAY buffer(BUFFERSIZE)
PTR ARRAY lines(100)
BYTE count=[0]

PROC AddLine(CHAR ARRAY line)
  CHAR ARRAY dst

  IF count=0 THEN
    dst=buffer
  ELSE
    dst=lines(count-1)
    dst==+dst(0)+1
  FI
  IF dst+line(0)+1>=buffer+BUFFERSIZE THEN
    Print("End of memory!")
    Break()
  FI
  SCopy(dst,line)
  lines(count)=dst
  count==+1
RETURN

PROC ReadFile(CHAR ARRAY fname)
  CHAR ARRAY line(255)
  BYTE dev=[1]

  Close(dev)
  Open(dev,fname,4)
  WHILE Eof(dev)=0
  DO
    InputSD(dev,line)
    AddLine(line)
  OD
  Close(dev)
RETURN

PROC Main()
  CHAR ARRAY s
  BYTE i,LMARGIN=$52,oldLMARGIN

  oldLMARGIN=LMARGIN
  LMARGIN=0 ;remove left margin on the screen
  Put(125) PutE() ;clear the screen

  ReadFile("H6:RODGERS.TXT")
  FOR i=0 TO count-1
  DO
    s=lines(count-1-i)
    PrintE(s)
  OD

  LMARGIN=oldLMARGIN ;restore left margin on the screen
RETURN
Output:

Screenshot from Atari 8-bit computer

                            --- Will Rodger

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Ada

with Ada.Text_Io;
with Ada.Containers.Indefinite_Vectors;
with Ada.Command_Line;

procedure Reverse_Lines_In_File is

   subtype Line_Number is Natural;

   package Line_Vectors
   is new Ada.Containers.Indefinite_Vectors
     (Index_Type   => Line_Number,
      Element_Type => String);

   use Line_Vectors,
     Ada.Text_Io,
     Ada.Command_Line;

   File   : File_Type;
   Buffer : Vector;
begin
   if Argument_Count = 1 then
      Open (File, In_File, Argument (1));
      Set_Input (File);
   end if;

   while not End_Of_File loop
      Buffer.Prepend (Get_Line);
   end loop;

   if Is_Open (File) then
      Close (File);
   end if;

   for Line of Buffer loop
      Put_Line (Line);
   end loop;

end Reverse_Lines_In_File;

ALGOL W

begin % reverse the order of the lines read from standard input %
    % record to hold a line and link to the next %
    record LinkedLine ( string(256) text; reference(LinkedLine) next );
    string(256) line;
    reference(LinkedLine) lines;
    % allow the program to continue after reaching end-of-file %
    ENDFILE := EXCEPTION( false, 1, 0, false, "EOF" );
    % handle the input %
    lines := null;
    readcard( line );
    while not XCPNOTED(ENDFILE) do begin
        lines := LinkedLine( line, lines );
        readcard( line )
    end while_not_eof ;
    % show the lines in reverse order %
    while lines not = null do begin
        integer len;
        % find the length of the line with trailing spaces removed %
        len := 255;
        line := text(lines);
        while len > 0 and line( len // 1 ) = " " do len := len - 1;
        % print the line, note Algol W does not allow variable length substrings %
        write( s_w := 0, line( 0 // 1 ) );
        for cPos := 1 until len do writeon( s_w := 0, line( cPos // 1 ) );
        lines := next(lines)
    end while_lines_ne_null
end.
Output:
                              --- Will Rodgers

 until you can find a rock."
     saying  'Nice Doggy'
   "Diplomacy is the art of

AWK

# syntax: GAWK -f REVERSE_THE_ORDER_OF_LINES_IN_A_TEXT_FILE_WHILE_PRESERVING_THE_CONTENTS_OF_EACH_LINE.AWK filename
{ arr[NR] = $0 }
END {
    for (i=NR; i>=1; i--) {
      printf("%s\n",arr[i])
    }
    exit(0)
}
Output:
                             --- Will Rodgers

 until you can find a rock."
    saying  'Nice Doggy'
  "Diplomacy is the art of


BASIC256

Translation of: FreeBASIC
source = freefile
open (source, "text.txt")
textEnt$ = ""
dim textSal$(size(source)*8)
linea = 0

while not eof(source)
	textEnt$ = readline(source)
	linea += 1
	textSal$[linea] = textEnt$
end while

for n = size(source) to 1 step -1
	print textSal$[n];
next n
close source
end
Output:
Igual que la entrada de FreeBASIC.


F#

// Reverse the order of lines in a text file while preserving the contents of each line. Nigel Galloway: August 9th., 2022
seq{use n=System.IO.File.OpenText("wr.txt") in while not n.EndOfStream do yield n.ReadLine()}|>Seq.rev|>Seq.iter(printfn "%s")
Output:
                             -- Will Rodgers

until you can find a rock."
    saying  'Nice Doggy'
  "Diplomacy is the art of

Factor

Works with: Factor version 0.99 2021-06-02
USING: io io.encodings.utf8 io.files sequences ;

"rodgers.txt" utf8 file-lines <reversed> [ print ] each
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
"Diplomacy is the art of

Delphi

See maybe Free Pascal

FreeBASIC

open "text.txt" for input as #1
dim as string textEnt, textSal()
dim as integer n, linea = 0

do while not eof(1)
    line input #1, textEnt
    linea += 1
    redim preserve textSal(linea)
    textSal(linea) = textEnt
loop

for n = ubound(textSal) to 1 step -1
    print textSal(n)
next n
close #1
sleep
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Free Pascal

program TAC;
{$IFDEF FPC}
  {$MODE DELPHI}
{$ELSE}
  {$APPTYPE CONSOLE}
{$ENDIF}
uses
  sysutils, classes;
var
  Sl:TStringList;
  i,j : nativeInt;
begin
  Sl := TStringList.Create;
  Sl.Loadfromfile('Rodgers.txt');
  i := 0;
  j := Sl.Count-1;
  While i<j do
  Begin
    Sl.Exchange(i,j);
    inc(i);
    dec(j);
  end;
  writeln(Sl.text);
end.
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Go

Translation of: Wren
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "log"
    "runtime"
)

func main() {
    fileName1 := "rodgers.txt"
    fileName2 := "rodgers_reversed.txt"
    lineBreak := "\n"
    if runtime.GOOS == "windows" {
        lineBreak = "\r\n"
    }
    // read lines from input file
    b, err := ioutil.ReadFile(fileName1)
    if err != nil {
        log.Fatal(err)
    }
    lines := bytes.Split(b, []byte(lineBreak))
    // remove final blank line, if any, added by some editors
    if len(lines[len(lines)-1]) == 0 {
        lines = lines[:len(lines)-1]
    }

    // write lines in reverse order to output file
    for i, j := 0, len(lines)-1; i < j; i, j = i+1, j-1 {
        lines[i], lines[j] = lines[j], lines[i]
    }
    b = bytes.Join(lines, []byte(lineBreak))
    if err = ioutil.WriteFile(fileName2, b, 0o666); err != nil {
        log.Fatal(err)
    }
    // print contents of output file to terminal
    b, err = ioutil.ReadFile(fileName2)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(b))
}
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Haskell

import qualified Data.Text as T
import qualified Data.Text.IO as TIO

main :: IO ()
main = TIO.interact $ T.unlines . reverse . T.lines
Output:
$ tac < tac.in
                             --- Will Rodgers

 until you can find a rock."
    saying  'Nice Doggy'
  "Diplomacy is the art of

J

   ;|.<;.2 text
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

where

text=: {{)n
 "Diplomacy is the art of
   saying  'Nice Doggy'
until you can find a rock."

                            --- Will Rodgers
}}

or

text=: fread 'filename'

if the text were stored in a file named filename.

jq

Works with: jq

Works with gojq, the Go implementation of jq

jq -nRr '[inputs] | reverse[]' input.txt
Output:
                             --- Will Rodgers

 until you can find a rock."
    saying  'Nice Doggy'
  "Diplomacy is the art of

Julia

The optional

keep

argument to

readlines

means to keep the newline '\n' char or '\r\n' digraph at the end of each line. The

|>

symbolism is the pipe operator. and the

.|>

symbolism means to pipe each line in the read array to print separately.

readlines("diplomacyrodgers.txt", keep=true) |> reverse .|> print
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Nim

We provide a procedure which takes input and output files as parameters. Assumptions are the following:

– a line is a sequence of bytes terminated by CR, LF or CR-LF;

– there is enough memory to process the file in memory i.e to store the input file as a string, the sequence of lines, the reverse sequence of lines and the output file as a string.

import algorithm, strutils

proc reverseLines(infile, outfile: File) =
  let lines = infile.readAll().splitLines(keepEol = true)
  outfile.write reversed(lines).join("")

when isMainModule:
  let infile = open("reverse_file_lines.txt")
  echo ">>>>> Input file:"
  stdout.write infile.readAll()
  infile.setFilePos(0)
  echo ">>>>>"
  echo '\n'
  echo ">>>>> Output file:"
  reverseLines(infile, stdout)
  echo ">>>>>"
Output:
>>>>> Input file:
 "Diplomacy is the art of
   saying  'Nice Doggy'
until you can find a rock."

                            --- Will Rodgers
>>>>>


>>>>> Output file:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of
>>>>>

OCaml

let rec read_lines_reverse lst =
  match read_line () with
  | line -> read_lines_reverse (line :: lst)
  | exception End_of_file -> lst

let () = read_lines_reverse [] |> List.iter print_endline
Output:
$ ocaml tac.ml <file.txt
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Pascal

See also Delphi and Free Pascal
The following is an ISO-compliant program. Some compilers, however, such as the FPC (Free Pascal Compiler) or Delphi, cannot handle files without file names.

program tac(input, output);

procedure reverse;
var
	line: text;
begin
	{ Open for (over-)writing. }
	rewrite(line);
	
	{ `EOLn` is shorthand for `EOLn(input)`. }
	while not EOLn do
	begin
		{ `line^` and `input^` refer to buffer variables [their values]. }
		line^ := input^;
		{ Write buffer and advance writing position. }
		put(line);
		{ Advance reading cursor and obtain next value [if such exists]. }
		get(input)
	end;
	
	{ Consume “newline” character in `input` }
	readLn;
	
	{ Likewise, `EOF` is shorthand for `EOF(input)`. }
	if not EOF then
	begin
		reverse
	end;
	
	{ (Re‑)open for reading. }
	reset(line);
	
	while not EOLn(line) do
	begin
		output^ := line^;
		put(output);
		get(line)
	end;
	
	{ `writeLn` is shorthand for `writeLn(output)`. }
	writeLn
end;

begin
	reverse
end.
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Note, this program will append a “new line” character to the final line if it did not exist.

Perl

as one-liner ..

// 20210803 Perl programming solution

< input.txt perl -e 'print reverse <>'
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Phix

with javascript_semantics
string text = """
 "Diplomacy is the art of
   saying  'Nice Doggy'
until you can find a rock."

                            --- Will Rodgers"""
if platform()!=JS then
    integer fn = open("rogers.txt","r")
    if fn=-1 then
        fn = open("rogers.txt","w")
        puts(fn,text)
        close(fn)
        fn = open("rogers.txt","r")
    end if
    text = substitute(get_text(fn),"\r\n","\n")
    close(fn)
end if
sequence lines = split(text,"\n",false)
printf(1,"%s\n",{join(reverse(lines),"\n")})

Obviously you can test the file handling by running the above, then changing eg Diplomacy to Diplomaxy and re-running it, and checking it outputs the previously saved c rather than the replacement x.

Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

Python

Interactive program which takes input from a file :

#Aamrun, 4th October 2021

import sys

if len(sys.argv)!=2:
    print("Usage : python " + sys.argv[0] + " <filename>")
    exit()

dataFile = open(sys.argv[1],"r")

fileData = dataFile.read().split('\n')

dataFile.close()

[print(i) for i in fileData[::-1]]

Input file :

 "Diplomacy is the art of                                    
   saying  'Nice Doggy'                                      
until you can find a rock."                                  
                                                             
                            --- Will Rodgers

Sample run and output:

Output:

C:\My Projects\BGI>python rosetta7.py diplomaticQuote.txt
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

C:\My Projects\BGI>

Quackery

  [ sharefile drop
    [] swap
    [ carriage over find split
      dup $ "" != while
      behead drop
      unrot nested swap join
      swap again ]
    drop nested swap join
    witheach [ echo$ cr ] ]    is task ( $ --> )

  $ "rosetta/input.txt" task
Output:
                            --- Will Rodgers
 
until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

R

text <- scan("Rodgers.txt", character(), sep = "\n")
print(text)
reversed <- rev(text)
print(reversed)
write(reversed, "SaveTheOutput.txt")
Output:
Read 5 items
[1] " \"Diplomacy is the art of"                  
[2] "   saying  'Nice Doggy'"                     
[3] "until you can find a rock.\""                
[4] " "                                           
[5] "                            --- Will Rodgers"
[1] "                            --- Will Rodgers"
[2] " "                                           
[3] "until you can find a rock.\""                
[4] "   saying  'Nice Doggy'"                     
[5] " \"Diplomacy is the art of"  

Raku

Not going to bother testing with the task recommended file. It demonstrates nothing to do with file handling, record separators, memory conservation or anything useful. May as well just be "Reverse this list" for all the good it does.

Lots of assumptions

Simplest thing that could possibly satisfy the extremely vague task description and completely glossing over all of the questions raised on the discussion page.

ASSUMPTIONS:

  • File is redirected into STDIN from command line.
  • Is a Unix or Windows format text file.
  • Is in UTF8 encoding or some subset thereof.
  • May hold entire file in memory.
.put for reverse lines

Few assumptions

Processes a small (configurable) number of bytes at a time so file can be multi-terabyte and it will handle with ease. Does assume Latin 1 for reduced complexity.

No assumptions were made concerning line/record termination, full stop.

Run the following to generate nul.txt. (digits 1 through 6 repeated 8 times with double null as record separators):

   raku -e'print join "\x00\x00", (1..6).map: * x 8' > nul.txt
my $input-record-separator = "\x00\x00";

my $fh = open("nul.txt".IO, :r, :bin);
$fh.seek(0, SeekFromEnd); # start at the end of the file

my $bytes = 5 min $fh.tell - 1; # read in file 5 bytes at a time (or whatever)

$fh.seek(-$bytes, SeekFromCurrent);

my $buffer = $fh.read($bytes).decode('Latin1'); # assume Latin1 for reduced complexity

loop {
    my $seek = ($fh.tell < $bytes * 2) ?? -$fh.tell !! -$bytes * 2;
    $fh.seek($seek, SeekFromCurrent);
    $buffer = $buffer R~ $fh.read((-$seek - $bytes) max 0).decode('Latin1');
    if $buffer.contains: $input-record-separator {
        my @rest;
        ($buffer, @rest) = $buffer.split: $input-record-separator;
        .say for reverse @rest; # emit any full records that have been processed
    }
    last if $fh.tell < $bytes;
}

say $buffer; # emit any remaining record
Output:
66666666
55555555
44444444
33333333
22222222
11111111

REXX

version 1

This will work for all REXXes,   but it reads all the file's lines/records into memory (storage or buffers).

No assumptions were made concerning line/record termination,   as REXX takes care of that.

/*REXX pgm reads a file, and displays the lines (records) of the file in reverse order. */
parse arg iFID .                                 /*obtain optional argument from the CL.*/
if iFID=='' | iFID=="," then iFID='REVERSEF.TXT' /*Not specified?  Then use the default.*/
call lineout iFID                                /*close file, good programming practice*/
                   do #=1  while lines(iFID)>0   /*read the file, one record at a time. */
                   @.#= linein(iFID)             /*assign contents of a record to array.*/
                   end   /*#*/
recs= # - 1                                      /*#  will be 1 more ('cause of DO loop)*/
                   do k=recs  by -1  for recs    /*process array (@.k) in reverse order.*/
                   say @.k                       /*display a record of the file ──► term*/
                   end   /*k*/
call lineout iFID                                /*close file, good programming practice*/
output   when using the default input:
                             --- Will Rodgers

 until you can find a rock."
    saying  'Nice Doggy'
  "Diplomacy is the art of

version 2

This will work for all the following REXXes   (and perhaps other REXXes as well):

  •   Regina REXX
  •   R4 REXX
  •   ROO REXX
  •   CMS REXX compiler
  •   CMS OREXX
/*REXX pgm reads a file, and displays the lines (records) of the file in reverse order. */
parse arg iFID .                                 /*obtain optional argument from the CL.*/
if iFID=='' | iFID=="," then iFID='REVERSEF.TXT' /*Not specified?  Then use the default.*/
call lineout iFID                                /*close file, good programming practice*/
options  nofast_lines_BIF_default                /*an option just for  Regina REXX.     */
#= lines(iFID)                                   /*#:  the number of lines in the file. */
                   do j=#  by -1  for #          /*read file (backwards), from bot──►top*/
                   say linein(iFID, j)           /*display record contents ──► terminal.*/
                   end   /*j*/
call lineout iFID                                /*close file, good programming practice*/
output   is identical to the 1st REXX version.



Ring

load "stdlib.ring"
see "working..." + nl
see "Input file lines:" + nl

fp = fopen("..\New\text.txt","r")
r = ""
txt = ""
while isstring(r)
      r = fgetc(fp)
      if r = -1
         loop
      ok
      if r = char(10)
         txt += nl
      else
         txt += r
      ok
end

see txt + nl
see "Reversed file lines: " + nl
txt = str2list(txt)
txt = reverse(txt)
txt = list2str(txt)
see txt
fclose(fp)  

see nl + "done..." + nl
Output:
working...
Input file lines:
 "Diplomacy is the art of
   saying  'Nice Doggy'
until you can find a rock."

                            --- Will Rodgers
Reversed file lines: 
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of
done...

Ruby

puts File.readlines("diplomacy.txt").reverse
Output:
                            --- Will Rodgers    

until you can find a rock." 
   saying  'Nice Doggy'
 "Diplomacy is the art of

sed

1!G
h
$!d
Output:
$ sed -f tac.sed file.txt
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

UNIX Shell

tac rodgers.txt
Output:
                            --- Will Rodgers
 
until you can find a rock."
   saying  'Nice Doggy'
"Diplomacy is the art of

Notice that tac is cat in reverse order.

Wren

Library: Wren-ioutil
import "./ioutil" for File, FileUtil

var fileName1 = "rodgers.txt"
var fileName2 = "rodgers_reversed.txt"

// read lines from input file
var lines  = FileUtil.readLines(fileName1)
// remove final blank line, if any, added by some editors
if (lines[-1] == "") lines.removeAt(-1)

// write lines in reverse order to output file
File.create(fileName2) { |file|
    for (i in lines.count-1..1) file.writeBytes(lines[i] + FileUtil.lineBreak)
    file.writeBytes(lines[0])
}
// print contents of output file to terminal
System.print(File.read(fileName2))
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of

XPL0

Usage: rev <will.txt

char    Array(1000, 1000);      \(tacky)
int     Line, Char, I;
def     LF=$0A, EOF=$1A;
[Line:= 0;
repeat  I:= 0;
        repeat  Char:= ChIn(1);
                Array(Line, I):= Char;  I:= I+1;
        until   Char = LF or Char = EOF;
        Line:= Line+1;
until   Char = EOF;
for Line:= Line-2 downto 0 do
        [I:= 0;
        repeat  Char:= Array(Line, I);  I:= I+1;
                ChOut(0, Char);
        until   Char = LF;
        ];
]
Output:
                            --- Will Rodgers

until you can find a rock."
   saying  'Nice Doggy'
 "Diplomacy is the art of