bash
can't detect the end of a file (without trying to read the next line and failing), but perl can with its eof
function:
$ perl -n -e 'print "Last " if eof; print "Direction: $_"' direction
Direction: east
Direction: north
Direction: south
Direction: west
Last Direction: south-west
note: unlike echo
in bash, the print
statement in perl doesn't print a newline unless you either 1. explicitly tell it to by including \n
in the string you're printing, or 2. are using perl's -l
command-line option, or 3. if the string already contains a newline....as is the case with $_
- which is why you often need to chomp()
it to get rid of the newline.
BTW, in perl, $_
is the current input line. Or the default iterator (often called "the current thingy" probably because "dollarunderscore" is a bit of a mouthful) in any loop that doesn't specify an actual variable name. Many perl functions and operators use $_
as their default/implicit argument if one isn't provided. See man perlvar
and search for $_
.
sed
can too - the $
address matches the last line of a file:
$ sed -e 's/^/Direction: /; $s/^/Last /' direction
Direction: east
Direction: north
Direction: south
Direction: west
Last Direction: south-west
The order of the sed
rules is important. My first attempt did it the wrong way around (and printed "Direction: Last south-west"). This sed script always adds "Direction: " to the beginning of each line. On the last line ($
) it adds "Last " to the beginning of the line already modified by the previous statement.
eof()
instead of justeof
....seeperldoc -f eof
for why. To get sed to behave like perl does, use the-s
option -sed -s -e '.....'
- this is a GNU extension to sed and may or may not be available in other versions. – cas Oct 12 '21 at 10:56use v5.10;
and then use thesay
function instead of print, which always appends a newline. – user1937198 Oct 12 '21 at 19:36print
. That para was explaining why the print function works to do what the OP wants - it doesn't output a newline unless you tell it to, which makes it useful to print a single line in stages. In shell, you'd have to useprintf
with a format string without a newline (you can't rely on the many incompatible variations ofecho
that offer different ways of doing that). perl'ssay
is a similar but different function...and btw, you can just use-E
instead of-e
to enable it, which is less typing thanuse v5.10;
or-Mv5.10
. – cas Oct 12 '21 at 22:45print
and using a separate substitution for the last line. (So that it also works when the last substitution doesn't contain the first):perl -pne 'if(eof) { s/^/Last Direction: /; } else { s/^/Direction: /; }' direction
– Garo Oct 13 '21 at 02:53