【问题标题】:Manipulate AWK field variables ($1,$2,..) and add that to the end of line操作 AWK 字段变量 ($1,$2,..) 并将其添加到行尾
【发布时间】:2019-09-13 09:55:01
【问题描述】:

我正在尝试从 ansible 库存文件创建 /etc/host 文件。

Ansible 库存文件如下所示:

[masters]
k8s-master-a.example.com ansible_ssh_host=10.15.90.2
k8s-master-b.example.com ansible_ssh_host=10.15.90.3
k8s-master-c.example.com ansible_ssh_host=10.15.90.4
[etcd]
k8s-etcd-a.example.com ansible_ssh_host=10.15.91.2
k8s-etcd-b.example.com ansible_ssh_host=10.15.91.3
k8s-etcd-c.example.com ansible_ssh_host=10.15.91.4

以下脚本将帮助使用 fqdn 条目创建它。

$cat inventory.yaml | grep -v '^\[' | sed 's/ansible_ssh_host=//g' | awk '{ print $2 " " $1}' > /etc/hosts
10.15.90.2 k8s-master-a.example.com  
10.15.90.3 k8s-master-b.example.com  
10.15.90.4 k8s-master-c.example.com  
10.15.91.2 k8s-etcd-a.example.com 
10.15.91.3 k8s-etcd-b.example.com 
10.15.91.4 k8s-etcd-c.example.com 

但我想在 /etc/hosts 文件中也有 k8s-master-* 和 k8s-etcd-* 。最终结果应该是这样的。

10.15.90.2 k8s-master-a.example.com k8s-master-a
10.15.90.3 k8s-master-b.example.com k8s-master-b
10.15.90.4 k8s-master-c.example.com k8s-master-c
10.15.91.2 k8s-etcd-a.example.com k8s-etcd-a
10.15.91.3 k8s-etcd-b.example.com k8s-etcd-b
10.15.91.4 k8s-etcd-c.example.com k8s-etcd-c

【问题讨论】:

    标签: linux awk sed cut


    【解决方案1】:

    您只需要 awk 即可。这将完成这项工作:

    cat inventory.yaml 
    [masters]
    k8s-master-a.example.com ansible_ssh_host=10.15.90.2
    k8s-master-b.example.com ansible_ssh_host=10.15.90.3
    k8s-master-c.example.com ansible_ssh_host=10.15.90.4
    [etcd]
    k8s-etcd-a.example.com ansible_ssh_host=10.15.91.2
    k8s-etcd-b.example.com ansible_ssh_host=10.15.91.3
    k8s-etcd-c.example.com ansible_ssh_host=10.15.91.4
    
    awk -F'[[:space:]=]' '/^[^[]/ {split($1, tokens, /[.]/); print $3, $1, tokens[1]}' inventory.yaml  
    10.15.90.2 k8s-master-a.example.com k8s-master-a
    10.15.90.3 k8s-master-b.example.com k8s-master-b
    10.15.90.4 k8s-master-c.example.com k8s-master-c
    10.15.91.2 k8s-etcd-a.example.com k8s-etcd-a
    10.15.91.3 k8s-etcd-b.example.com k8s-etcd-b
    10.15.91.4 k8s-etcd-c.example.com k8s-etcd-c
    

    【讨论】:

    • 当然!几乎是一样的。 :-)
    【解决方案2】:

    AWK 解决方案:

    awk -F'[ =]' '/^[^\[]/ { if (match($1,/\./)) print($NF " " $1 " " substr($1,0,RSTART-1)); }'
    

    测试:

    $ awk -F'[ =]' '/^[^\[]/ { if (match($1,/\./)) print($NF " " $1 " " substr($1,0,RSTART-1)); }' inventory.yaml
    10.15.90.2 k8s-master-a.example.com k8s-master-a
    10.15.90.3 k8s-master-b.example.com k8s-master-b
    10.15.90.4 k8s-master-c.example.com k8s-master-c
    10.15.91.2 k8s-etcd-a.example.com k8s-etcd-a
    10.15.91.3 k8s-etcd-b.example.com k8s-etcd-b
    10.15.91.4 k8s-etcd-c.example.com k8s-etcd-c
    

    【讨论】:

    • awk 中的字符串、字段和数组索引从 1 开始,而不是 0,因此对于 substr() 的第二个参数,0 是无效值。您只能从中获得您想要的输出,因为 awk 将该上下文中的所有无效值都视为 1。用substr($0,-127,RSTART-1) 试试,你会得到同样的结果。因此,将substr($0,0 更改为substr($0,1,以便代码使用有效值。使用print $NF, $1, ... 而不是硬编码" "OFS。您无需在括号表达式 /^[^[]/ 内转义 [ 即可。
    • 另外,既然你想从字面上对待.,你应该只使用s=index($1,"."),它需要一个文字字符串,而不是使用match(),它需要一个正则表达式,然后转义.,所以它被处理了字面上地。显然你会在substr() 调用中使用s-1 而不是RSTART-1
    【解决方案3】:

    如果 'd' 文件中有数据,请在 gnu awk 上尝试:

    awk -F'[.= ]' '$0!~/^\[/{print $5"."$6"."$7"."$8,$1,$2"."$3,$1}' d
    

    【讨论】:

      【解决方案4】:
      $ awk -F'[=[:space:]]+' 'split($1,f,/[.]/)>1{print $NF, $1, f[1]}' file
      10.15.90.2 k8s-master-a.example.com k8s-master-a
      10.15.90.3 k8s-master-b.example.com k8s-master-b
      10.15.90.4 k8s-master-c.example.com k8s-master-c
      10.15.91.2 k8s-etcd-a.example.com k8s-etcd-a
      10.15.91.3 k8s-etcd-b.example.com k8s-etcd-b
      10.15.91.4 k8s-etcd-c.example.com k8s-etcd-c
      

      【讨论】:

        猜你喜欢
        • 2020-08-27
        • 2010-09-05
        • 2016-11-08
        • 2011-11-03
        • 1970-01-01
        • 2019-12-18
        • 2021-01-04
        • 1970-01-01
        • 2012-12-09
        相关资源
        最近更新 更多