对在bash输出中找不到的字符串执行PIPE

时间:2018-12-19 07:01:02

标签: bash awk sed grep xargs

我想要的结果流程如下:但是不确定在这里如何使用for循环。请在我的表达式中观察每个节点的输出中都不存在试图验证string1的地方。

  • 获取与DISABLED字符串匹配的命令的输出,该字符串给出了匹配节点的列表。 例如:

    kubectl get nodes | grep -i DISABLED
    

    示例:输出为

    node1-DISABLED node2-DISABLED node3-DISABLED
    
  • 对于上面得到的每个节点,我都像在描述它们 例如:

    kubectl describe nodes $1
    
  • 然后在describe的输出中,我想查看所有节点的describe输出命令中没有“ string1”字符串的内容,然后如果找不到,则回显/打印该节点

所以我的完整表情看起来像这样

kubectl get nodes | grep -i DISABLED | 
awk -F ' ' '{print $1}' | 
xargs -l1 -- sh -c 'kubectl describe node "$1"' | 
for grep -e "string1" == 0; do 
xargs -l1 -- sh -c 'echo "$1"' --; done

部分命令的输出示例:

bash$ kubectl get nodes | grep -i DISABLED
10.4.5.15-59fa4f88   Ready,SchedulingDisabled   node      20d       v1.10.9   <none>        Ubuntu 16.04.4 LTS   4.15.0-15-generic   docker://18.3.1

10.4.5.16-59fa4f88   Ready,SchedulingDisabled   node      20d       v1.10.9   <none>        Ubuntu 16.04.4 LTS   4.15.0-15-generic   docker://18.3.1


bash$ kubectl get nodes | grep -i DISABLED | awk -F ' ' '{print $1}'
10.4.5.15-59fa4f88
10.4.5.16-59fa4f88

预期输出为:

10.4.5.15-59fa4f88

因为节点10.4.5.15-59fa4f88在其输出描述中没有string1,并且未回显10.4.5.16,因为其描述中的描述输出中有string1。

基本上,我正在尝试构建一个描述每个节点的表达式并检查其中的string1,如果没有,它将把该节点回显到终端。

的输出
kubectl describe node $1

Name:               10.4.5.15-59fa4f88
Roles:              node
Labels:             beta.kubernetes.io/arch=amd64
                beta.kubernetes.io/instance-type=gdd5_8dd.dd2xlarge
                beta.kubernetes.io/os=linux
                failure-domain.beta.kubernetes.io/zone=sdjcd2d01-sw-05
                kops.k8s.io/instancegroup=nodes-test
                kubernetes.io/hostname=10.4.5.15-59fa4f88
                kubernetes.io/role=node
                node-role.kubernetes.io/node=
Annotations:        d.volume.kubernetes.io/nodeid={"d-d":"10.4.5.15-59fa4f88"}
                node.alpha.kubernetes.io/ttl=0
                volumes.kubernetes.io/controller-managed-attach-detach=true
CreationTimestamp:  Wed, 28 Nov 2018 07:37:39 -0800
Taints:             <none>

1 个答案:

答案 0 :(得分:1)

我认为您的代码可以大大简化。试试这个:

kubectl get nodes |
# Awk can do everything grep can do, and then some
awk 'toupper($0) ~ /DISABLED/ { print $1 }' |
# loop over results
while read -r node; do
    kubectl describe node "$node" |
    grep -q "string1" || echo "$node"
done

如果kubectl describe node的输出中某处包含节点名称(例如,第一个字段?),则while循环可能会替换为类似的

# xargs already knows how to run a command
xargs -n 1 kubectl describe node |
# Simply filter out anything with string1
awk '! /string1/ { print $1 }'

如果您要清除重复项,请使用| sort -u,或者在后一种情况下,请在Awk脚本中实施简单的重复项删除(提示:保留您所看到的值的关联数组,并且仅在出现某些情况时才打印尚未在数组中。)

已更新,以响应编辑:这是Awk尝试,如果输出均不包含start1,则提取并打印“名称:”字段。

kubectl get nodes |
awk 'toupper($0) ~ /DISABLED/ { print $1 }' |
xargs -n 1 kubectl describe node |
awk '/^Name: / { if (NR>1 && name) print name
        name=$2 }
    /string1/ { name="" }
    END { if (name) print name }'

Awk脚本在看到新输出的开始时将分配name。如果设置了先前的name,那么我们首先将其打印(先前的记录)。如果第二个正则表达式看到name,则会取消设置string1,以便在我们到达下一个记录时不会打印它。最后,在END中,我们将捕获姓氏(如果已设置)。