Issue
I'm trying to print lines € [N;$-M] where $ is the address of the last line :
So far, I tried this :
$ sed -n '71,-61 p' myLogFile
sed: -e expression #1, char 4: unexpected `,'
and that :
$ sed -n '71,$-61 p' myLogFile
sed: -e expression #1, char 5: unknown command: `-'
BTW: N and M are not shell variables.
EDIT0 : My bad, sed
is a stream editor (I thank @jhnc for this recall) therefore it cannot tell the number of lines in advance. The $
referring to the address of the last line can only be used in text editors of the vi
family.
So I have to use another tool to do this.
Solution
sed
is designed to work on piped input. It doesn't know in advance how long the input will be. Until the final line has been read, sed
does not know how many lines remain to be processed.
It is possible to implement the desired behaviour in sed if the input is buffered before printing. For example:
$ ntom(){
n=$1
m=$2
file=$3
sed -nE '
'$n' {
# initialise buffer (avoids leading newline)
h
d
}
'$n',$ {
# append to buffer
H
$!d
# print buffer after final line read
# delete unneeded lines off end
x
s/(\n[^\n]*){'$m'}$//p
}
' "$file"
}
$ ntom 71 61 myLogFile
but it is probably simpler to use tail
and head
:
$ tail -n +71 myLogFile | head -n -61
Implementations of tail
and head
often use a (circular) buffer on piped input too. They can be more efficient if input is seekable.
Also, as ed
expects seekable input, as long as the file is not too big, you could use your original syntax with it:
echo '71,$-61p' | ed -s myLogFile
Answered By - jhnc Answer Checked By - Gilberto Lyons (WPSolving Admin)