【问题标题】:Bash edit file and keep last 500 linesBash 编辑文件并保留最后 500 行
【发布时间】:2010-05-21 09:11:21
【问题描述】:

我正在寻找一个 cron 作业,它打开一个目录循环遍历我创建的所有日志并删除所有行,但保留最后 500 行。

我在想一些类似的东西

tail -n 500 filename > filename

这行得通吗?

我也不确定如何在 bash 中遍历目录。

【问题讨论】:

  • 查看其他答案,但您的示例 tail 行执行如下:1)外壳打开文件名以输出并将其截断为零长度 2)尾部运行,看到一个空文件和 3)不向现在为空的文件名写入任何内容。 MYYN 的答案显示了您如何避免这种情况,但如果tail 遇到错误,即使是炸弹也会爆炸。不要重新发明 tanascius 推荐的 logrotate。

标签: bash logging tail


【解决方案1】:

如果要截断的日志文件当前已被某些服务打开,那么在前面的答案中使用 mv 将中断这些服务。这可以通过使用 cat 轻松克服:

tail -n 1000 myfile.log > myfile.tmp
cat myfile.tmp > myfile.log

【讨论】:

  • 救了我的培根……两次!当您在演示前 6 分钟以 99% 的速度面对 df -h 时,这几乎是一种学习的权利。
【解决方案2】:

考虑使用logrotate
它不会做你想做的事情(删除除最后 500 行之外的所有行),但它可以处理大于特定大小的日志文件(通常通过压缩旧文件并在某个时候删除它们)。应该可以广泛使用。

【讨论】:

    【解决方案3】:

    在我看来,最简单、最快的方法是使用变量:

    LASTDATA=$(tail -n 500 filename)
    echo "${LASTDATA}" > filename
    

    【讨论】:

    • 对于那些像我一样匆忙的人,那些是变量名周围的大括号......
    【解决方案4】:
    DIR=/path/to/my/dir # log directory
    TMP=/tmp/tmp.log # temporary file
    for f in `find ${DIR} -type f -depth 1 -name \*.log` ; do
      tail -n 500 $f > /tmp/tmp.log
      mv /tmp/tmp.log $f
    done
    

    【讨论】:

    • for foo in $(find) 是养成的坏习惯。使用find | while read 或通配符。而mv 应该以tail 的成功为条件。
    • @Dennis:谢谢 - 你能解释一下为什么for foo in $(find ...) 是个坏习惯吗?
    • 如果有带空格的文件名,它会将它们视为多个单独的名称。
    【解决方案5】:

    在 bash 中,您循环遍历目录中的文件,例如像这样:

    cd target/directory
    
    for filename in *log; do
        echo "Cutting file $filename"
        tail -n 500 $filename > $filename.cut
        mv $filename.cut $filename
    done
    

    【讨论】:

    • mv 应该以tail 的成功为条件。
    猜你喜欢
    • 2011-12-15
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2016-09-14
    • 2014-01-13
    • 1970-01-01
    相关资源
    最近更新 更多