๐ŸŽ„ 21/25. Merging files horizontally in Perl 6

๐ŸŽ„ 21/25. Merging files horizontally in Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.

Welcome to Day 21 of the Perl 6 One-Liner Advent Calendar! Only a few days left until the end of this season of advent calendars, so letโ€™s pack as many things as possible in the remaining days, and today we’ll merge a few files into a single file ๐Ÿ™‚

Our todayโ€™s goal is to take two (or three, or more) files and copy their contents line by line. For example, we want to merge two log files, knowing that all their lines correspond to each other.

File a.txt:

2018/12/20 11:16:13
2018/12/20 11:17:58
2018/12/20 11:19:18
2018/12/20 11:24:30

File b.txt:

"/favicon.ico" failed (No such file)
"/favicon.ico" failed (No such file)
"/robots.txt" failed (No such file)
"/robots.txt" failed (No such file)

Our first one-liner illustrates the idea:

.say for [Z~] @*ARGS.map: *.IO.lines;

It is assumed that the program is run as follows:

$ perl6 merge.pl a.txt b.txt

For each filename (@*.ARGS.map) in the command line, an IO::Path object is created (.IO), and the lines from the files are read (.lines).

In the case of two files, we have two sequences, which are then concatenated line by line using the zip meta-operator Z applied to a concatenation infix ~.

After that step, we get another sequence, which we can print line by line (.say for).

2018/12/20 11:16:13"/favicon.ico" failed (No such file)
2018/12/20 11:17:58"/favicon.ico" failed (No such file)
2018/12/20 11:19:18"/robots.txt" failed (No such file)
2018/12/20 11:24:30"/robots.txt" failed (No such file)

The result is formally correct, but letโ€™s add a space between the original lines. Here is an updated version of the one-liner:

.trim.say for [Z~] @*ARGS.map: *.IO.lines.map: *~ ' '

Here, a space character is appended to the end of each line (.map: *~ ' '), and as there will be one extra space at the end of the combined line, it is removed by the trim method. Its sibling, trim-trailing, could be used instead (or a regex if you care about original trailing spaces happened to be in the second file).

With the above change, the files are perfectly merged now:

2018/12/20 11:16:13 "/favicon.ico" failed (No such file)
2018/12/20 11:17:58 "/favicon.ico" failed (No such file)
2018/12/20 11:19:18 "/robots.txt" failed (No such file)
2018/12/20 11:24:30 "/robots.txt" failed (No such file)

Thereโ€™s no problem to merge the same file to itself, or to provide more than two files, for example:

$ perl6 merge.pl a.txt a.txt a.txt

That was it for today, come again tomorrow!

2 thoughts on “๐ŸŽ„ 21/25. Merging files horizontally in Perl 6”

Leave a Reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code