简体   繁体   中英

PHP or Linux Shell: Fastest way to reduce a text file that has more than 10 lines to only have the last 10 lines

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM