【问题标题】:Format the ouput of df command without newlines格式化不带换行符的 df 命令的输出
【发布时间】:2019-03-28 03:11:12
【问题描述】:

我有一个脚本正在运行,它建立一个远程 SSH 隧道并运行以下代码来检查可用磁盘空间并使用 AWK 进行格式化并报告为:

#!/bin/bash
for DATA in $(sudo df -h | grep -E '/$|/var$|/tmp$' | awk '{print $1","$5","$6}' | tr -d '%')
    do
        DISK=$(echo $DATA | awk -F, '{print $1}')
        FREE=$(echo $DATA | awk -F, '{print $2}')
        MOUNT=$(echo $DATA | awk -F, '{print $3}')
        if [[ "$FREE" -ge '90' ]]
            then
                echo "$HOST does not have enough room to patch, \"$MOUNT\" ($DISK) is ${FREE}% full"
        fi
    done

我特意删除了运行所需的转义 正确地在远程外壳上(为了可读性)

这运行良好,除非行太长并且 df 跨行剪切输出,如下所示:

这会弄乱 for 循环并返回错误数据。我想要关于如何格式化换行符的任何建议。我用 sed/tr/printf 尝试了几件事,我参考了这两个 printf 备忘单:

我参考了其他标题相似的帖子,并且已经尝试导出 COLUMNS,但这似乎没有任何作用。

感谢您的反馈,谢谢。

编辑:df (GNU coreutils) 8.4

【问题讨论】:

  • 这是什么版本的df? GNU coreutils 实现似乎没有这个问题,尽管busybox 有。重新格式化的明显方法是注意续行没有足够的字段,并且续行以空格开头
  • df (GNU coreutils) 8.4
  • edit 您的问题包括minimal reproducible example 以及一些文本示例输入和预期输出,以便我们为您提供帮助。

标签: bash awk printf


【解决方案1】:
df -h | awk '
    NF == 1 {device = $1; getline; $0 = device $0}
    {sub(/%/, "", $5); print $1 "," $5 "," $6}
'

awk 正文的第一行将查看当前行是否只有 1 个字段。如果是,请记住设备,读取下一行,然后将设备插入(新)当前行。

对于您突出显示的项目,这应该输出:

/dev/mapper/vg_01-lv_var,16,/var

您可以从管道中删除 grep 和 tr。


您的 shell 循环需要大量改进。而不是进入那个,你可以在 awk 中完成所有工作:

df -h | awk -v host="$HOST" -v limit=90 '
    BEGIN {msg = "%s does not have enough room to patch, \"%s\" (%s) is %s full\n"}
    NR == 1 {next}
    NF == 1 {device = $1; getline; $0 = device $0}
    $5 >= limit {printf msg, host, $6, $1, $5}
'

【讨论】:

  • 您提供的代替我的 for 循环的 AWK 语句运行良好,谢谢!由于我一直在寻求提高我的编码能力,您能否分享一下 for 循环需要改进的地方?要么在这里,要么在 DM 中。谢谢。
  • 基本上:1) 将代码粘贴到shellcheck.net 2) 不要使用全大写变量名,3) 读取mywiki.wooledge.org/BashFAQ/001
  • 非常感谢!我多年来一直在使用 shellcheck.net。始终使用 CAPS 表示变量,使用 CamelCase 表示函数。我更喜欢数组而不是 while 循环,但这只是我。感谢您的反馈,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
相关资源
最近更新 更多