首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用BASH,如何扩展PDSH IP地址列表?

使用BASH,如何扩展PDSH IP地址列表?
EN

Stack Overflow用户
提问于 2013-08-07 04:55:38
回答 4查看 1.1K关注 0票数 0

我有一个大约3000个IP地址的列表,这些地址是通过dshback -c传输的pdsh输出的结果,该输出将输出格式化为可读格式。我喜欢dshback -c的可读性,但我遇到的问题是,具有普通八进制的IP被折叠以节省空间。我需要有完整的IP地址为我的项目的其余部分。

是否有一种简单的方法来转换此输入:

代码语言:javascript
复制
192.168.38.[217,222],192.168.40.215,192.168.41.[219-222]

对于此输出:

代码语言:javascript
复制
192.168.38.217,192.168.38.222,192.168.40.215,192.168.41.219,192.168.41.220,192.168.41.221,192.168.41.222

我认为sed可以直接使用,但我不知道如何将普通的八进制存储在变量中。因此,我相信bash脚本将需要与sed一起使用。任何帮助或指向正确的方向将不胜感激。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-08-07 05:23:44

如果可以更改输入,可以使用以下形式:

代码语言:javascript
复制
echo 192.168.38.{217,222} 192.168.40.215 192.168.41.{219..222} | tr ' ' ','

否则,您可以通过命令和eval来更改它:

代码语言:javascript
复制
eval echo $( echo '192.168.38.[217,222],192.168.40.215,192.168.41.[219-222]' | \
 sed 's/,/ /g;s/\[/{/g;s/]/}/g;s/-/../g;s/\({[0-9]\+\) \([0-9]\+}\)/\1,\2/g' | \
 grep -v '[^0-9{}., ]' ) | tr ' ' ','

注意,对于失效的数据,eval非常危险,因此我使用grep '[^0-9{}., ]'来排除任何意外的符号。此命令中的sed只是将原始字符串转换为我前面提到的表单。

票数 1
EN

Stack Overflow用户

发布于 2013-08-07 06:08:48

如果您已经准备好使用awk,那么可以尝试以下方法

代码语言:javascript
复制
echo "192.168.38.[217,222],192.168.40.215,192.168.41.[219-222]" |sed 's/\[//g' | sed 's/\]//g' | awk -F, '{for(i=1;i<=NF;i++){n=split($i,a,".");IPL="";if(n>1){PIP=a[1] "." a[2] "." a[3];}else{IPL=PIP "." $i;}if(index(a[4],"-") > 0){x=0;split(a[4],b,"-");for(j=b[1];j<=b[2];j++){if(x==0){IPL=PIP "." j;x++;}else{IPL=IPL "," PIP "." j;}}}else if(index(a[4],",") > 0){split(a[4],b,",");IPL=PIP "." b[1] "," PIP "." b[2];}else{if(length(IPL)<=3){IPL=PIP "." a[4];}}printf("%s,",IPL);}}'

如果你对此感兴趣,我可以解释一下逻辑.

票数 0
EN

Stack Overflow用户

发布于 2013-08-07 06:15:12

这是一种完全根据需要使用Bash处理它的方法。没有鹰嘴,苏木和其他东西。

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

shopt -s extglob
IFS=,

while read -r LINE; do
    OUTPUT=()
    while [[ -n $LINE ]]; do
        case "$LINE" in
        +([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]))
            OUTPUT[${#OUTPUT[@]}]=$LINE
            break
            ;;
        +([[:digit:]]).+([[:digit:]]).+([[:digit:]]).+([[:digit:]]),*)
            OUTPUT[${#OUTPUT[@]}]=${LINE%%,*}
            LINE=${LINE#*,}
            ;;
        +([[:digit:]]).+([[:digit:]]).+([[:digit:]]).\[+([[:digit:],-])\]*)
            SET=${LINE%%\]*}
            PREFIX=${SET%%\[*}
            read -a RANGES <<< "${SET:${#PREFIX} + 1}"
            for R in "${RANGES[@]}"; do
                case "$R" in
                +([[:digit:]]))
                    OUTPUT[${#OUTPUT[@]}]=${PREFIX}${R}
                    ;;
                +([[:digit:]])-+([[:digit:]]))
                    X=${R%%-*} Y=${R##*-}
                    if [[ X -le Y ]]; then
                        for (( I = X; I <= Y; ++I )); do
                            OUTPUT[${#OUTPUT[@]}]=${PREFIX}${I}
                        done
                    else
                        for (( I = X; I >= Y; --I )); do
                            OUTPUT[${#OUTPUT[@]}]=${PREFIX}${I}
                        done
                    fi
                    ;;
                esac
            done
            LINE=${LINE:${#SET} + 2}
            ;;
        *)
            # echo "Invalid token: $LINE" >&2
            break
        esac
    done
    echo "${OUTPUT[*]}"
done

的输入

代码语言:javascript
复制
192.168.38.[217,222],192.168.40.215,192.168.41.[219-222]

运行bash temp.sh < temp.txt产量

代码语言:javascript
复制
192.168.38.217,192.168.38.222,192.168.40.215,192.168.41.219,192.168.41.220,192.168.41.221,192.168.41.222

这也和范围一致。如果X比Y晚,例如200-100,那么它将生成200到100子集的IPS。脚本还可以处理多行输入。

它也应该适用于诸如100,200-250这样的混合范围。

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

https://stackoverflow.com/questions/18094954

复制
相关文章

相似问题

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