This could be a good job for the shell's read
builtin - as long as your input is text, that is, and doesn't contain any \0NUL
s. I say this because, though it is often terribly inefficient for file work when compared with other standard utilities, using a shell builtin would likely be better than repeatedly forking another process. And you won't get much efficiency anyway because the only way to do this (that I know of) is to repeatedly open()
your output file - unless you can be very sure of the number of bytes per line (which might be assured with a few chained dd
s in a pipeline, I guess). In any case, the following will work:
###seq used for demo###
seq 3 |( set --
while IFS= read -r l
do set -- "$@" "$l"
shift "$(($#>4))"
printf %s\\n "$@" >/tmp/4_lines
###demo commands###
printf '\n###4_lines CONTENTS###\n'
cat </tmp/4_lines
printf '###END###\n'
###end demo###
done)
So if I do the above as written this is written to the while
loop's stdout:
###4_lines CONTENTS###
1
###END###
###4_lines CONTENTS###
1
2
###END###
###4_lines CONTENTS###
1
2
3
###END###
But if I hand seq
20, for example, it prints the above then:
###4_lines CONTENTS###
1
2
3
4
###END###
###4_lines CONTENTS###
2
3
4
5
###END###
...all the way up to...
###4_lines CONTENTS###
16
17
18
19
###END###
###4_lines CONTENTS###
17
18
19
20
###END###
It will go on like that until the input pipe is closed - just round-robining its arg array and overwriting /tmp/4_lines
with the array's contents each time an input line is read
. If you wanted the lines in reverse order - so the first line is the last line read in, you could change the printf
line to:
printf %s\\n ${4+"$4"} ${3+"$3"} ${2+"$2"} "$1" >/tmp/4_lines
...which would print like...
###4_lines CONTENTS###
1
###END###
###4_lines CONTENTS###
2
1
###END###
###4_lines CONTENTS###
3
2
1
###END###
...through...
###4_lines CONTENTS###
19
18
17
16
###END###
###4_lines CONTENTS###
20
19
18
17
###END###
...without risking any difficulties with $IFS
and/or unintentional globs on the expansion.
out.txt
– Kokizzu Feb 09 '15 at 04:04/tmp
(ramfs) and symlink it to/var/www
directory – Kokizzu Feb 09 '15 at 04:15./program > out.txt
and when you need to look at the file, usetail -4 out.txt
. Thetail
command won't read the whole file each time; it will seek to the end and then 'scan backwards' to find the last four lines. – Jonathan Leffler Feb 10 '15 at 15:04