I need to know the fastest way possible, in PHP or Linux Command Shell, to reduce a text file that has more than 10 lines to only have the last 10 lines. I want to use 10 lines for this example.
Thanks :)
to reduce a file to it's last then lines do
tail -n 10 /path/to/file > /path/to/file.tmp && rm /path/to/file && mv /path/to/file.tmp /path/to/file
explanation:
tail
outputs the last n
lines of a file. >
writes it to a file. &&
is for chaining commands. rm
removes a file. mv
renames a file (or moves to a different location).
If you really really don't want to generate a new file, then you might try
echo "$(tail -n 10 path/to/file)" >path/to/file
The $()
works just like backticks (it evaluates whatever's inside and equates to the output of said command), except it works better in strings. On my Linux machine, the string gets evaluated (meaning tail
is run) before the output goes to the file (which is what causes the problems with tail file >file
; the file gets opened -- and truncated -- as soon as the command starts). I'm thinking it's because echo
is a builtin, but don't quote me on that.
EDIT: Actually, i took a closer look. It's because the tail
is in a string. There are several phases -- here, the ones we care about are interpolation, redirection and execution -- that always happen in a certain defined order (namely, the order just given). And in the process of interpolating the string, Bash has to run the command within it. Before any redirection is done. With a straight tail file >file
, the tail
program is what actually generates the output, so no output happens til the command is executed -- but the file's already been opened for writing (due to redirection) right before that, and opening that file for writing truncates it.)
phase tail file >file echo "$(tail file)" >file
-------------+---------------------------------+-------------------------------
interpolate nothing run "tail file"; get output (+)
redirect open file for write; set stdout open file for write; set stdout
execute run "tail file" (*) run 'echo "line\nline\n..."'
(*)
: Note, since file
was already opened for writing by this point, it's now truncated. So tail
reads 0 bytes.
(+)
: Since file
was read in before the redirection opened it for writing, tail
manages to see all the data.
Even though the behavior is obviously defined and predictable, this still feels kinda hacky to me. It relies on bash arcana, and may very well cause memory issues if you try to get too many or too long lines. (I tested with ~500 char lines, and didn't see any issues. But haven't tested with more than 10 lines yet.) It'd probably be better to use a temp file unless you need to preserve the same inode number for some odd reason.
tail -n 10 yourfile > yourfile.tmp && mv yourfile.tmp yourfile
编辑为仅提供可能大于10行的文件的最后10行。
In linux you could do
tail -n 10 path/to/file > path/to/output/file
This will take the last ten lines (# of lines specified by value after -n) of the file and then append them to another file.
If you want to overwrite the existing file with only its last ten lines then do
tail -n 10 path/to/file > path/to/output/file && mv path/to/output/file path/to/file
Note the first example outputs to a different file while the second overwrite the existing file.
You could also do this in PHP by using exec() with the shell command inside, or the more laborious way of reading the entire file into an array with file() and then taking the last ten elements of the array and adding them back into the file with fwrite() or similar.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.