1

我需要知道在 PHP 或 Linux Command Shell 中最快的方法,以将超过 10 行的文本文件减少到只有最后 10 行。我想在这个例子中使用 10 行。

谢谢 :)

4

4 回答 4

3

将文件减少到最后一个然后行

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重命名文件(或移动到不同的位置)。

于 2012-07-25T19:55:14.310 回答
1

如果您真的不想生成新文件,那么您可以尝试

echo "$(tail -n 10 path/to/file)" >path/to/file

$()就像反引号一样工作(它评估内部的任何内容并等同于所述命令的输出),但它在字符串中效果更好。tail在我的 Linux 机器上,字符串在输出到文件之前被评估(意思是运行)(这是导致问题的原因tail file >file;文件被打开 - 并被截断 - 只要命令启动)。 我在想这是因为它echo是内置的,但不要引用我的话。

编辑: 实际上,我仔细看了看。这是因为tail在字符串中。有几个阶段——在这里,我们关心的是插值、重定向和执行——总是以特定的定义顺序发生(即,刚刚给出的顺序)。在插入字符串的过程中,Bash 必须在其中运行命令。在完成任何重定向之前。使用直行tail file >filetail程序是实际生成输出的东西,因此在执行命令之前不会发生输出 - 但在此之前已经打开文件进行写入(由于重定向),并且打开该文件进行写入会截断它。 )

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 编号,否则使用临时文件可能会更好出于某种奇怪的原因。

于 2012-07-25T21:38:27.290 回答
0
tail -n 10 yourfile > yourfile.tmp && mv yourfile.tmp yourfile

编辑为仅给出文件的最后 10 行,可能超过 10 行。

于 2012-07-25T19:55:36.287 回答
0

在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() 或类似文件的文件。

于 2012-07-25T19:55:38.053 回答