I'm using GNU Coreutils on Windows. I want to get last error line from log file
The SED regex works fine (but finds first entry in file)
c:\path\sed -n "/70\-Error/{p;q}" MyFile.log
the TAC command
c:\path\tac MyFile.log
successfully reverses the whole file, without error
but when I combine the two I get the last match line from the file output, as expected, but also an error:
c:\path\tac MyFile.log | c:\path\sed -n "/70\-Error/{p;q}"
gives
14/02/2018 10:19:03 [9] 70-Error: Errorcode: Query returned error 524 (Query timeout)
c:\path\tac: write error: Invalid argument
EDIT:
sed -n "p" MyFile.log
gives output
sed -n "p" MyFile.log | cat
also gives output, with no error
sed -n "p" MyFile.log | sed -n "/70\-Error/{p;q}"
gives first matching line and error:
30/01/2018 10:30:28 [7] 70-Error: Action failed ....
sed: couldn't write 225 items to stdout: Broken pipe
Using CAT isntead of TAC:
cat MyFile.log | sed -n "/70\-Error/{p;q}"
gives first matching line then error - looks same as TAC scenario:
30/01/2018 10:30:28 [7] 70-Error: Action failed ...
cat: write error: Invalid argument
Other tests:
sed -n "/fe80::a828:2146:58d1:28df/{p}" MyFile.log
is fine but
sed -n "/fe80::a828:2146:58d1:28df/{p}" MyFile.log | tac
gives no output and only this error instead:
sed: couldn't flush stdout: Invalid argument
I thought the problem might be associated with the fact that MyFile.log had a full path, including spaces, and as such was quoted - so I copied MyFile.log to same folder as GNU tools so everything was in current folder and no complex filename ... but same thing.
sed -n "p" MyFile.log | tac
gives (first) 25 lines from file, in reverse order, then:
sed: couldn't write 225 items to stdout: Broken pipe
maybe some sort of memory / cache-size limitation?
sed --unbuffered
didn't change anything.
MyFile.log is 4MB and 27,000 lines
EDIT2:
tac MyFile.log | sed "/70\-Error/h;$!d;x"
works fine, even for quoted MyFile.log containing spaces
This might work for you (GNU sed):
sed '/70\\-Error/h;$!d;x' file
This copies an error message into the hold space and at the end of file prints it.
N.B. Uses \\
to represent \
as a single backslash is a quoting metacharacter in sed.
To print all the lines following the last error message use:
sed '/70-Error/h;//!H;$!d;x' file
To print a selective number of lines following the last error message, say 3, use:
sed '/70-Error/h;//!H;$!d;x;s/\(\(\n[^\n]*\)\{3\}\).*/\1/' file
Or, more easy on the eye:
sed -r '/70-Error/h;//!H;$!d;x;s/((\n[^\n]*){3}).*/\1/' file