我需要知道在 PHP 或 Linux Command Shell 中最快的方法,以将超过 10 行的文本文件减少到只有最后 10 行。我想在这个例子中使用 10 行。
谢谢 :)
将文件减少到最后一个然后行
tail -n 10 /path/to/file > /path/to/file.tmp && rm /path/to/file && mv /path/to/file.tmp /path/to/file
解释:
tail
输出n
文件的最后几行。
>
将其写入文件。
&&
用于链接命令。
rm
删除一个文件。
mv
重命名文件(或移动到不同的位置)。
如果您真的不想生成新文件,那么您可以尝试
echo "$(tail -n 10 path/to/file)" >path/to/file
$()
就像反引号一样工作(它评估内部的任何内容并等同于所述命令的输出),但它在字符串中效果更好。tail
在我的 Linux 机器上,字符串在输出到文件之前被评估(意思是运行)(这是导致问题的原因tail file >file
;文件被打开 - 并被截断 - 只要命令启动)。 我在想这是因为它echo
是内置的,但不要引用我的话。
编辑: 实际上,我仔细看了看。这是因为tail
在字符串中。有几个阶段——在这里,我们关心的是插值、重定向和执行——总是以特定的定义顺序发生(即,刚刚给出的顺序)。在插入字符串的过程中,Bash 必须在其中运行命令。在完成任何重定向之前。使用直行tail file >file
,tail
程序是实际生成输出的东西,因此在执行命令之前不会发生输出 - 但在此之前已经打开文件进行写入(由于重定向),并且打开该文件进行写入会截断它。 )
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..."'
(*)
:请注意,由于file
此时已打开以供写入,因此现在已被截断。所以tail
读取 0 个字节。
(+)
:由于在重定向打开它进行写入之前file
被读入,因此可以看到所有数据。tail
尽管行为显然是定义和可预测的,但这对我来说仍然有点骇人听闻。它依赖于 bash arcana,如果您尝试获取太多或太长的行,很可能会导致内存问题。(我测试了大约 500 个字符行,没有发现任何问题。但还没有测试超过 10 行。)除非您需要保留相同的 inode 编号,否则使用临时文件可能会更好出于某种奇怪的原因。
tail -n 10 yourfile > yourfile.tmp && mv yourfile.tmp yourfile
编辑为仅给出文件的最后 10 行,可能超过 10 行。
在linux中你可以做
tail -n 10 path/to/file > path/to/output/file
这将获取文件的最后十行(由 -n 之后的值指定的行数),然后将它们附加到另一个文件。
如果您只想用最后十行覆盖现有文件,请执行
tail -n 10 path/to/file > path/to/output/file && mv path/to/output/file path/to/file
注意第一个示例输出到不同的文件,而第二个示例覆盖现有文件。
您也可以在 PHP 中通过使用 exec() 和内部的 shell 命令来执行此操作,或者更费力的方法是使用 file() 将整个文件读入一个数组,然后取出数组的最后十个元素并将它们添加回带有 fwrite() 或类似文件的文件。