Raku Books / Raku One-Liners / Working with Files

Reversing a file

In this section, we are creating a one-liner to print the lines of a text file in reversed order (as tail -r does it).

The first one-liner does the job with the STDIN stream:

.say for $*IN.lines.reverse

Run the program as:

$ raku reverse.raku < text.txt

$*IN can be omitted in this case, which makes the one-liner even shorter:

.say for lines.reverse

If you want to read the files directly from Raku, modify the program a bit to create a file handle out of the command-line argument:

.say for @*ARGS[0].IO.open.lines.reverse

🖥 This program reads the local environment (files, directories, or the command line), so it runs on your own computer but not in the sandboxed in-browser engine.

Now you run it as follows:

$ raku reverse.raku text.txt

It is important to remember that the default behaviour of the lines method is to exclude the newline characters from the final sequence of lines (the method returns a Seq object, not an array or a list).

In Raku, the lines method splits the lines based on the value stored in the .nl-in attribute of the IO::Handle object.

You can look at the current value of the line separators with the following tiny script:

dd $_ for @*ARGS[0].IO.open.nl-in

🖥 This program reads the local environment (files, directories, or the command line), so it runs on your own computer but not in the sandboxed in-browser engine.

This is what you find there by default:

$["\n", "\r\n"]

The interesting thing is that you can control the behaviour of lines and tell Raku not to exclude the newline characters:

@*ARGS[0].IO.open(chomp => False).lines.reverse.put

🖥 This program reads the local environment (files, directories, or the command line), so it runs on your own computer but not in the sandboxed in-browser engine.

The chomp attribute is set to True by default. You can also change the default separator:

@*ARGS[0].IO.open(
    nl-in => "\r", chomp => False
).lines.reverse.put

🖥 This program reads the local environment (files, directories, or the command line), so it runs on your own computer but not in the sandboxed in-browser engine.

Notice that without chomping, you do not need an explicit for loop over the lines: in the last two one-liners, the .put method is called directly on the sequence object. In the earlier versions, the strings did not contain the newline characters, and thus they would be printed as a single long line.

A small homework for you: Tell the difference between put and say.

Course navigation

Merging files horizontally   |   Working with Numbers