【问题标题】:Bash one-liner code to output unique valuesBash 单行代码以输出唯一值
【发布时间】:2017-08-10 12:18:11
【问题描述】:

我有这个命令会输出 0、1 或 2。

这行代码是配置文件 (zabbix) 的一部分,是单行代码的唯一原因。

mysql -u root -e  "show slave status\G" | \
grep -E 'Slave_IO_Running:|Slave_SQL_Running:' | cut -f2 -d':' | \
sed "s/No/0/;s/Yes/1/" | awk '{ SUM += $1} END { print SUM }'

但我希望它输出的值是这样的,这样我就可以设置具有正确状态的警报:

如果只有Slave_IO_RunningNo 则输出1。

如果只有Slave_SQL_RunningNo 则输出2。

如果两者都是Yes,则输出3。

如果两者都是No,则输出0。

如果show slave status 命令没有行/输出,则输出 4。

因此,例如使用 sed 或 awk 使用唯一值修改 No 的第一个条目。以及具有唯一值的第二个条目,依此类推。

show slave status\G的输出

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.10.10.10
                  Master_User: replicationslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.009081
          Read_Master_Log_Pos: 856648307
               Relay_Log_File: mysqld-relay-bin.002513
                Relay_Log_Pos: 1431694
        Relay_Master_Log_File: mysql-bin.009081
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

【问题讨论】:

  • 您能否仅包含mysql -u root -e "show slave status\G" 命令的输出,以便我们更好地了解您正在处理哪些数据,并测试我们可能提出的解决方案?
  • 您可以使用if 语句而无需运行两次查询,变量的存在是有原因的。
  • 注意,如果你用管道结束一行,你不需要换行反斜杠 -- bash 知道你还没有完成。

标签: bash awk grep


【解决方案1】:

你可以在awk这里做所有的字符串处理:

mysql -u root -e  "show slave status\G" | awk 'BEGIN {output=0} /Slave_IO_Running.*No/ {output+=1} /Slave_SQL_Running.*No/ {output +=2} END {if(output==3}{print 0} else {if(output==0} {print 3} else {print output}}'

这将从0 开始输出计数器,如果我们将Slave_IO_RunningNo 匹配,我们将添加1。如果我们将Slave_SQL_RunningNo 匹配,我们将添加2,然后在末尾我们将打印总数,如果两者都不匹配,则为 0,如果只有 IO 为 No,则为 1,如果只有 SQL 为 No,则为 2,如果两者都为 No,则为 3。由于您要打印 0,如果两者都是 Yes,我们将反转最后我们的计数,如果我们得到一个 3 那么两个都是“否”所以打印 0,否则如果它是 0 打印 3,否则打印它自己的值。

【讨论】:

  • 对您的答案进行一些解释会很可爱。
  • @ghoti 已经被低估了,尽管我随后看到了关于想要 3 的问题的编辑,如果两者都是肯定的,并且必须稍微解决一些问题
  • 谢谢。我认为您的第一次编辑还可以。如果两者都是,则返回 0。如果两者都为否,则返回 3。我实际上正在使用您的第一次编辑。如果我应该更新一个,请纠正我。我不介意哪个数字,但值必须是唯一的,以便我可以将每个值分配给一个状态。
  • 如果你不介意是0还是3,那我就用第一个,比较简单
  • 编辑建议包括“else if (NR==0) print 4;”因为如果由于任何问题没有输出,我们可以打印 4.
【解决方案2】:

如果您有这样做的冲动,可以将以下 awk 代码压缩成一行:

awk -F: -v ret=0 '
  /Slave_IO_Running:.*No/ { ret=1 }
  /Slave_IO_Running:.*Yes/ { yes++ }
  /Slave_SQL_Running:.*No/ { ret=(ret==1) ? 0 : 2 }
  /Slave_SQL_Running:.*Yes/ { yes++ }
  END { print (yes==2) ? 3 : ret }
'

没有grepcutsed 是必需的,这将直接获取您的mysql 命令的输出。它还假定Slave_IO_Running 在您的命令输出中始终出现在Slave_SQL_Running 之前。

第三行和最后一行中的符号用作内联“if”语句——如果ret的值等于1,则将ret设置为0;否则将ret 设置为2

【讨论】:

    【解决方案3】:

    只要您的数据中有名称到值对,通常最清晰、最简单和最容易在以后增强时首先创建一个将名称映射到值的数组,然后通过它们的名称访问值,例如:

    awk '
    { f[$1]=$2 }
    END {
        if (f["Slave_10_Running:"] == "Yes")
            rslt = (f["Slave_SQL_Running:"] == "Yes" ? 3 : 2)
        else
            rslt = (f["Slave_SQL_Running:"] == "Yes" ? 1 : 0)
        print rslt
    }
    ' file
    1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 2019-08-19
      • 2019-02-01
      • 2012-11-14
      相关资源
      最近更新 更多