2. Processing files (read)

2.1 Create

Basically, all code below is an extension of

$ perl -e 'expression' file
by adding switches, multiple expressions and files, e.g.:

$ perl switches -e 'expression-1; expression-2; ... expression-n;' file-1 file-2 ... file-n

2.2 Access

The switch -n add loops to the -e code, so you can process files a line at a time. And each line will be put into the special variable $_

For demonstration purposes, let's first create two text files with some content.

The first file name_age_1.txt contains four lines (format is name:age)

Sebastian:41
Daniel:39
Florence:37
Hannah:8


The second file name_age_2.txt contains also four lines (format is name:age)

Kirsten:42
Bibian:40
Niki:36
Elle:5


To loop through the content of the file name_age_1.txt, write

$ perl -n -e '$_;' name_age_1.txt # each line of name_age_1.txt will be put into $_
To loop through the content of multiple file, e.g. name_age_1.txt and name_age_2.txt:

$ perl -n -e '$_;' name_age_1.txt name_age_2.txt
So, now both filenames are added as argument.

2.3 Print

2.3.1 Print contents of a file
To print all lines from name_age_1.txt, type

$ perl -n -e 'print("$_");' name_age_1.txt # each line of name_age_1.txt will be put into $_
or

$ perl -n -e 'print;' name_age_1.txt
The commandline switches can be combined: -ne

$ perl -ne 'print("$_");' name_age_1.txt (1)
However, I prefer the first option (with separated commandline switches). It is completely clear what it does:

$ perl -n -e 'print("$_");' name_age_1.txt (1)

2.3.2 Print contents of multiple files
To print all records from both files, type

$ perl -n -e 'print("$_");' name_age_1.txt name_age_2.txt

2.3.3 Add a linenumber
Put a line number to the lines of the file via the special variable $.

$ perl -n -e 'print("$. : $_");' name_age_1.txt

2.4 Iterate

Iteration has already been discussed.

2.5 Operate

2.5.1 Filtering contents of a file
To show only the lines that contain the name daniel, use a regex:

$ perl -n -e 'print("$_") if (/daniel/);' name_age_1.txt
To show only the lines with an even linenumber:

$ perl -n -e 'print("$_") if (! $. % 2);' name_age_1.txt
To show only the first two lines:

$ perl -n -e 'print($_) if ++$count < 3;' name_age_1.txt
If App::pl is installed, it's still easier:

$ pl -rp2 '' name_age_1.txt
or the last two lines (knowing the file has 4 lines):

$ pl -P '3..eof' name_age_1.txt
or the last line:

$ pl -e Echo '' name_age_1.txt
alternatively:

$ pl -P 'eof' name_age_1.txt
which outputs the last line also.

2.5.2 Print names of a file name_age_1.txt
You've to use the -a switch (with option –n) to split the lines of the file into sets of words, assuming white space (default) as the field separators. To specify another pattern as field separator, the –F option is used followed by the delimiter (here -F:). In all cases, the resulting list is stored in the special array @F. $F[0] refers to first 'column' which contains the name.

$ perl -F: -l -a -n -e 'print($F[0]);' name_age_1.txt
outputs:

Sebastian
Daniel
Florence
Hannah

2.5.3 Print names which are a palindrome in name_age_1.txt and name_age_2.txt

$ perl -F: -l -a -n -e 'print() if (length($F[0]) > 3 and (uc($F[0])) eq reverse(uc($F[0])));' name_age_1.txt name_age_2.txt
outputs:

Hannah
Elle

2.5.4 Print the average age in name_age_1.txt
Here you've to use END to indicate the last action (after calculating the variables sum and count), i.e. printing the average:

$ perl -F: -l -a -n -e '$sum = $sum + $F[1];$count++;END{print($sum/$count)};' name_age_1.txt
outputs:

31.25

2.5.5 Use module
With Mmodule you can load a module. With Statistics::Lite (https://metacpan.org/pod/Statistics::Lite) you can calculate statistical values such as min, max, mean, median in an array. Let's rewrite the last code. I make first an array with the age data and apply then the statistical function mean:

$ perl -MStatistics::Lite=:all -F: -l -a -n -e 'push(@ages,$F[1]);END{print(mean @ages);};' name_age_1.txt
outputs (of course):

31.25
Notice that -MStatistics::Lite=:all is equivalent to use Statistics::Lite qw(:all); which you would use in a script file.
Footnotes
(1) There is a shorter one: $ perl -p -e '' name_age_1.txt The switch -p loops and prints.