【问题标题】:Need uniq output for df -h and remove duliplicate values需要 df -h 的 uniq 输出并删除重复值
【发布时间】:2020-01-17 05:29:07
【问题描述】:

我在下面创建了用于 Jason 输出的 shell 脚本。我得到了正确的结果输出,但也显示了很少的 deplicte 挂载点。我想通过删除重复来获得 uniq 输出

disks=$(ssh username@${server} df -h |\
egrep "/ABC" | \
awk '{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}' && \
ssh username@${server} df -h |\
egrep "/XYZ" | \
awk '{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}'
 && \
ssh username@${server} df -h |\
egrep "/RRR" |\
awk '{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}' && ssh username@${server} df -h |egrep "/CCC" | awk '{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "}"}')

我现在得到的输出是:

976M   92M  834M  10% /ABC
2.0G  3.5M  1.9G   1% /ABC---- duplicate mount points (need to remove one entry. i.e. /AAA)
99G   23G   71G  25% /XYZ
500G   53G  448G  11% /RRR

【问题讨论】:

  • 我现在得到的输出是:976M 92M 834M 10% /ABC 2.0G 3.5M 1.9G 1% /ABC---- 重复的挂载点(需要删除一个条目。即/AAA) 99G 23G 71G 25% /XYZ 500G 53G 448G 11% /RRR
  • 我现在得到的输出是:976M 92M 834M 10% /ABC 2.0G 3.5M 1.9G 1% /ABC---- 重复的挂载点(需要删除一个条目。即/AAA) 99G 23G 71G 25% /XYZ 500G 53G 448G 11% /RRR
  • 您不需要运行df -h 4 X。运行一次并让您的awk 脚本使用/\/RRR/{do stuff for RRR recs}; /\/CCC/{ do stuff for CCC recs}... etc 之类的模式匹配。正如现在所写的那样,您的 Q 太难阅读了,并且您使用 disks=$(...) 使其复杂化。东西,只要让awk 过滤器工作,然后你可以在最后添加disks=$(..)。使用 cmets 中提供的信息更新您的 Q,或者删除它们,因为它们看起来像重复信息。在鼠标选择的文本上使用编辑菜单中的{} 工具来获得正确的文本/数据/errMsgs 格式。祝你好运。
  • awk 是这个工作的错误工具。使用像 jq 这样的工具,它本身就知道如何生成有效的、正确引用的 JSON。
  • 你为什么要写这段代码?为什么要运行df 三个不同的时间?为什么不运行awk 一次,从单个df 调用的输出中过滤出您关心的三个挂载点?

标签: shell awk ssh grep disk


【解决方案1】:

1。你可以省略 egrep

由于您使用的是awk,您可以完全省略egrep 并缩短您的代码。

代替

ssh <> | egrep <pattern> | awk '{<commands>}'

你可以使用

ssh <> | awk '<pattern> {<commands>}'

即:

disks=$(ssh username@${server} df -h |\
awk '/\/ABC/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}' &&\
ssh username@${server} df -h  | \
awk '/\/XYZ/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}' && \
ssh username@${server} df -h  | \
awk '/\/RRR/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"}' && \
ssh username@${server} df -h  | \
awk '/\/CCC/{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "}"}')

2。 awk: 如何只打印第一次出现的模式

你可以试试这个:

awk '/regex/ {print $1; exit}'

disks=$(ssh username@${server} df -h | \
awk '/\/ABC/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"; exit}' && \
ssh username@${server} df -h  | \
awk '/\/XYZ/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"; exit}' && \
ssh username@${server} df -h  | \
awk '/\/RRR/ {print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "},"; exit}' && \
ssh username@${server} df -h  | \
awk '/\/CCC/{print "{" "\"total\":" "\"" $3 "\"" ", \"used\":" "\"" $4"\"" ", \"mountPoint\":" "\""$5"\"" "}"; exit}')

附言 有大量的awk样本:Useful One-Line Scripts for awk command.

【讨论】:

    【解决方案2】:

    更适合这项工作的工具是jq。考虑一下(请注意,测试此的人应该更改 ABC|XYZ|RR 正则表达式以匹配至少一个本地挂载点):

    df -h | jq -R '
      select(test("/(ABC|XYZ|RR)/"; "")) |
      split("[[:space:]]+"; "") as $line |
      { "total": $line[3], "used": $line[4], "mountPoint": $line[5] } 
    '
    

    awk 不理解 JSON 语法,因此如果您的挂载点名称包含需要转义以使输出文档有效的字符,awk 不知道这样做。相比之下,jq 会自动执行所有引用和转义,以使输出成为有效的 JSON,无论您的输入是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多