首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只创建一个循环以生成列表- Shell

只创建一个循环以生成列表- Shell
EN

Stack Overflow用户
提问于 2021-03-11 19:38:58
回答 3查看 52关注 0票数 0

我想要创建一个具有特定配置的.xml文件,这个配置需要一个主机名和一个ip,我已经创建了hosts.csv来输入这些数据,它们是.csv file上的每个分隔行的vm-tmb-test1;127.0.0.1";"是服务器的主机名和ip,但是在hosts.csv中为每个ip创建了循环打印。

码结构

代码语言:javascript
复制
#!/bin/bash

for i in $(cat /var/projects/etc/hosts.csv | cut -d\; -f1)
do
    for ips in $(cat /var/projects/etc/hosts.csv | cut -d\; -f2)
    do
        if [[ ${i} == *"jua"* ]]
        then
            sed -i '$ a <node name="'${i}'" tags="infra,jua,vm" hostname="'${ips}'" username="test"/>' /var/projects/etc/resources.xml
        elif [[ ${i} == *"tmb"* ]]
        then
            sed -i '$ a <node name="'${i}'" tags="infra,tmb,vm" hostname="'${ips}'" username="tests"/>' /var/projects/etc/resources.xml 
        fi
    done
done

Host.csv内容:

代码语言:javascript
复制
vm-tmb-test1;127.0.0.1
vm-tmb-test2;127.0.0.2
vm-tmb-test3;127.0.0.3
vm-jua-test4;127.0.0.4

期望产出:

代码语言:javascript
复制
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test3" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-jua-test4" tags="infra,jua,vm" hostname="127.0.0.4" username="test"/>

实际代码输出:

代码语言:javascript
复制
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.4" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.4" username="test"/>

我怎么才能解决呢?

编辑1: host.csv包含更多的200台服务器,主机名和ip,它将随着时间的推移而提供。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-03-11 20:49:30

虽然存在更快的解决方案(例如,awksed),但对于这个答案,我将坚持OP使用循环的想法。

样本输入:

代码语言:javascript
复制
$ cat host.csv
vm-tmb-test1;127.0.0.1
vm-tmb-test2;127.0.0.2
vm-tmb-test3;127.0.0.3
vm-jua-test4;127.0.0.4

由于示例代码似乎只是将输出附加到一个*.xml文件中,所以我将选择一个生成所需输出的while循环:

代码语言:javascript
复制
while IFS=";" read -r i ips                             # use ';' as input delimiter and read values into our 2 variables 'i' and 'ips'
do
        tag='UNDEFINED'                                 # define some defaults in case 'i' does not 
        uname='UNDEFINED'                               # have a match in our case statement

        case "${i}" in                                  # pattern match 'i' to determine what strings to submit to the printf command
                *jua*)  tag='jua' ; uname='test'   ;;
                *tmb*)  tag='tmb' ; uname='tests'  ;;
        esac

        printf '<node name="%s" tags="infra,%s,vm" hostname="%s" username="%s"/>\n' "${i}" "${tag}" "${ips}" "${uname}"

done < host.csv

以上所述产生:

代码语言:javascript
复制
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="tests"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="tests"/>
<node name="vm-tmb-test3" tags="infra,tmb,vm" hostname="127.0.0.3" username="tests"/>
<node name="vm-jua-test4" tags="infra,jua,vm" hostname="127.0.0.4" username="test"/>

注意到

destination

  • this
  • OP可以将printf的输出重定向到最终的printf,这比重复的sed -i调用
  • 要高一些--我复制了OPs代码片段,显示了username="{test|tests}"的使用(尽管OP的示例输出仅显示字符串test);OP可以根据需要编辑建议的代码(

< code >F 220)

票数 1
EN

Stack Overflow用户

发布于 2021-03-11 19:49:48

一个GNU sed调用可以完成以下工作:

代码语言:javascript
复制
sed -E 's/([^-]*)-([^-]*)-([^;]*);(.*)/<node name="\1-\2-\3" tags="infra,\2,\1" hostname="\4" username="test"\/>/' file
票数 1
EN

Stack Overflow用户

发布于 2021-03-11 21:05:22

while循环解决方案推入单个awk调用:

代码语言:javascript
复制
awk -F";" '                              # input delimiter is ";"
           { tag="UNDEFINED" }           # default tag in case $1 does not match the following patterns
$1 ~ /jua/ { tag="jua"       }
$1 ~ /tmb/ { tag="tmb"       }

           { printf "<node name=\"%s\" tags=\"infra,%s,vm\" hostname=\"%s\" username=\"test\"/>\n", $1, tag, $2 }
' host.csv

这就产生了:

代码语言:javascript
复制
<node name="vm-tmb-test1" tags="infra,tmb,vm" hostname="127.0.0.1" username="test"/>
<node name="vm-tmb-test2" tags="infra,tmb,vm" hostname="127.0.0.2" username="test"/>
<node name="vm-tmb-test3" tags="infra,tmb,vm" hostname="127.0.0.3" username="test"/>
<node name="vm-jua-test4" tags="infra,jua,vm" hostname="127.0.0.4" username="test"/>

注意到

再次,OP可以将username="test"的输出重定向到最终的输出文件(或者,将awk调用的全部输出定向到所述输出文件)

  • ,对于这个答案,我假设所有输出都应该具有相同的字符串

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66589388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档