dor*_*and 26 command-line logs tail
我尝试在我的文件中保留最后 50 行,每分钟保存一次温度。我使用了这个命令:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test
Run Code Online (Sandbox Code Playgroud)
但结果是空的测试文件。我想,它会列出测试文件的最后 50 行并将其插入到测试文件中。当我使用此命令时:
tail -n 50 /home/pi/Documents/test > /home/pi/Documents/test2
Run Code Online (Sandbox Code Playgroud)
它工作正常。test2 文件中有 50 行。
有人能解释一下问题出在哪里吗?
Rah*_*hul 33
问题是您的 shell 在运行命令之前设置了命令管道。这不是“输入和输出”的问题,而是文件的内容在 tail 运行之前就已经消失了。它是这样的:
>输出文件进行写入,截断它tail.tail运行,打开/home/pi/Documents/test并在那里找不到任何东西有多种解决方案,但关键是要了解问题、实际出现的问题以及原因。
这将产生你正在寻找的东西,
echo "$(tail -n 50 /home/pi/Documents/test)" > /home/pi/Documents/test
Run Code Online (Sandbox Code Playgroud)
解释 :
$() 被称为执行的命令替换 tail -n 50 /home/pi/Documents/test> /home/pi/Documents/test将输出重定向echo "$(tail -n 50 /home/pi/Documents/test)"到同一个文件。文件重定向首先清除文件的另一种解决方案是sponge从moreutils包中使用,如下所示:
tail -n 50 /home/pi/Documents/test | sponge /home/pi/Documents/test
Run Code Online (Sandbox Code Playgroud)
这是因为 bash 使用第>一个处理重定向,删除文件的内容。然后它执行命令。如果您使用>>,最后 50 行将附加到文件中当前内容的末尾。在这种情况下,您将重复两次相同的 50 行。
该命令在重定向到其他文件时按预期工作。这是将文件的最后 50 行写入同名文件的一种方法:
tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 && mv /home/pi/Documents/test2 /home/pi/Documents/test
Run Code Online (Sandbox Code Playgroud)
这首先将最后 50 行写入临时文件,然后将其移动mv以替换原始文件。
如评论中所述,如果文件仍处于打开状态,这将不起作用。移动文件还会创建一个新的 inode,并且可能会更改所有权和权限。使用临时文件执行此操作的更好方法是:
tail -50 /home/pi/Documents/test > /home/pi/Documents/test2 ; cat /home/pi/Documents/test2 > /home/pi/Documents/test
Run Code Online (Sandbox Code Playgroud)
临时文件也可以删除,但每次发生这种情况时,其内容都会被覆盖。
printf '%s\n' '1,$-50d' w | ed -s /home/pi/Documents/tes
Run Code Online (Sandbox Code Playgroud)
printf用于将命令(每行一个)通过管道传输到ed. 命令ed是:
1,$-50d -- 删除除最后 50 行以外的所有行w -- 将修改后的文件写回磁盘不涉及重定向,因此 shell 在读取输出文件之前无法覆盖它。
此外,与大多数形式的“就地”编辑(通常仅通过创建临时文件然后在原始文件上重命名来模拟“就地”编辑)不同,ed实际上编辑了原始文件 - 因此它保留相同的索引节点(以及所有者、组和权限 - tempfile + mv 将始终更改 inode,并可能根据情况更改其他内容)。
| 归档时间: |
|
| 查看次数: |
17143 次 |
| 最近记录: |