【问题标题】:Select everything but a block of text选择除文本块之外的所有内容
【发布时间】:2017-03-28 14:17:28
【问题描述】:

我有一个用于分布式网络监控系统的综合主机文件,我需要将其拆分为两个文件。一些主机放在一个文件中,其余的放在另一个文件中。我正在使用sed 来拉出我需要的主机,但我不知道如何将其他所有内容放入另一个文件中,有点像grep-v 选项。

主机文件示例:

object Host "router" {
  import "template"
  display_name = "router"
  address = "xx.xx.xx.xx "
}

object Host "switch" {
  import "template"
  display_name = "switch"
  address = "xx.xx.xx.xx "
}

object Host "router" {
  import "template"
  display_name = "router"
  address = "xx.xx.xx.xx "
}

object Host "otherthing" {
  import "template"
  display_name = "otherthing"
  address = "xx.xx.xx.xx "
}

object Host "switch" {
  import "template"
  display_name = "switch"
  address = "xx.xx.xx.xx "
}

object Host "otherthing" {
  import "template"
  display_name = "otherthing"
  address = "xx.xx.xx.xx "
}

我用来拉出路由器的sed 命令

sed '/router.*\n/p;//g;/{$/,/^}/H;//x;D' files/tmp/unsorted-host.tmp >> files/router.conf

另外我不知道排序是否比构建大型主机文件更有效,但这是我制作大型主机文件的方法:

    while read line
        do
                # The SNMP to check the device type outputs on multiple lines, check to ensure we only grab IP's
                getip=$(echo $line | awk '{print $1}')
                if ping -c 1 $getip &> /dev/null
                        then
                        ip=$getip
                        else
                        trash=$getip
                fi
                template="template"
                host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community1 $ip 1.3.6.1.2.1.1.5.0 | awk '{print $NF}' )
                if [ -z "$host_name" ]
                        then
                        host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community2 $ip 1.3.6.1.2.1.1.5.0 | awk '{print $NF}' )
                        if [ -z "$host_name" ]
                                then
                                host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community3 $ip 1.3.6.1.2.1.1.5.0 | awk '{print $NF}' )
                                if [ -z "$host_name" ]
                                        then
                                        host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community4 $ip 1.3.6.1.2.1.1.5.0 | awk '{print $NF}' )
                                        if [ -z "$host_name" ]
                                                then
                                                host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community5 $ip 1.3.6.1.2.1.1.5.0 | awk '{print $NF}' )
                                                if [ -z "$host_name" ]
                                                        then
                                                        host_name=$(echo " Not found ")

                                                fi
                                        fi
                                fi
                        fi
                fi
                echo "
object Host $host_name {
  import \"$template\"
  display_name = $host_name
  address = \"$ip \"
}" 
        done < files/tmp/hosts.tmp > files/tmp/unsorted-hosts.tmp

目标是拥有两个文件,一个包含路由器,一个包含其他所有文件。提前感谢您的任何建议!

【问题讨论】:

  • 我没有详细查看您的sed 声明,但是如果您能够使用sed 找到您需要的一切,那么您不能也只做一个sed替换删除路由器材料?

标签: bash ubuntu awk sed grep


【解决方案1】:

使用 awk:

awk -v RS= '/router/' hosts.txt > routers.txt
awk -v RS= '!/router/' hosts.txt > non_routers.txt

或使用一个 awk:

awk -v RS= '/router/ {print > "routers.txt"}; !/router/ {print > "non_routers.txt"}' hosts.txt

见:8 Powerful Awk Built-in Variables – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

【讨论】:

    【解决方案2】:

    这不是答案:我发现嵌套的大 if 很痛苦。快速重写:

    while read -r ip rest_of_line; do
        # The SNMP to check the device type outputs on multiple lines, check to ensure we only grab IP's
        ping -c 1 "$ip" &> /dev/null || continue
        template="template"
        host_name=
        for n in 1 2 3 4 5; do
            host_name=$(timeout -s KILL 2 /usr/bin/snmpwalk -v 2c -c community$n "$ip" 1.3.6.1.2.1.1.5.0 | awk '{print $NF}')
            [ -n "$host_name" ] && break
        done
        if [ -z "$host_name" ]; then 
            echo "host not found for ip $ip" >&2
            continue
        fi
        echo "
    object Host $host_name {
      import \"$template\"
      display_name = $host_name
      address = \"$ip \"
    }" 
    done < files/tmp/hosts.tmp > files/tmp/unsorted-hosts.tmp
    

    【讨论】:

    • 我希望我能做这样的事情,但社区实际上是文本字符串。出于隐私考虑,我只是将它们替换为 community1 community2 等。
    • 然后做for c in community1 community2 community3 ...
    • 我试试看,谢谢!这个网站真的很棒,你们都帮了大忙。
    猜你喜欢
    • 2016-01-11
    • 1970-01-01
    • 2016-11-03
    • 2021-01-25
    • 2012-08-05
    • 2010-11-26
    • 1970-01-01
    • 2021-11-27
    • 2021-04-21
    相关资源
    最近更新 更多