我有以下文件
more /etc/hosts
23.1.22.162 kafka01.dfg.com
23.1.22.155 kafka02.dfg.com
23.1.22.222 kafka03.dfg.com
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
我们想在 master
和 worker
时捕获所有 kafka_name=""
和 egrep
机器,所以我们这样做了
kafka_name=""
egrep "\smaster|\sworker|\s$kafka_name" /etc/hosts
但我们仍然得到主机包括 kafka 机器
egrep "\smaster|\sworker|\s$kafka_name" /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
23.1.22.162 kafka01.dfg.com
23.1.22.155 kafka02.dfg.com
23.1.22.222 kafka03.dfg.com
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
无论如何当我们设置
kafka_name="kafka"
我们也得到了 kafka 机器
egrep "\smaster|\sworker|\s$kafka_name" /etc/hosts
23.1.22.162 kafka01.dfg.com
23.1.22.155 kafka02.dfg.com
23.1.22.222 kafka03.dfg.com
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
那为什么当我们设置
kafka_name=""
尽管 $kafka_name
为空,它是否仍然从主机打印 kafka 机器?
答案 0 :(得分:3)
仅供参考 egrep
已弃用,而支持 grep -E
。
不过,请考虑使用 awk,以便对您想要表达的任何条件(不仅仅是正则表达式 - 条件)进行清晰、简单的控制,例如:
$ kafka_name=''
$ awk -v kafka_name="$kafka_name" '( $2 ~ /^(master|worker)/ ) || ( (kafka_name != "") && ($2 ~ ("^"kafka_name)) )' file
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
$ kafka_name='kafka02'
$ awk -v kafka_name="$kafka_name" '( $2 ~ /^(master|worker)/ ) || ( (kafka_name != "") && ($2 ~ ("^"kafka_name)) )' file
23.1.22.155 kafka02.dfg.com
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
以上代码可以在任何 Unix 机器上的任何 shell 中使用任何 awk。
它使用正则表达式而不是字符串比较,就像在您的 egrep
命令中所做的那样,因此如果这些名称中的任何一个可以包含正则表达式元字符,您需要将它们转义或将脚本更改为在任何地方使用 index($2,string) == 1
而不是 $2 ~ /^regexp/
,例如:
$ awk -v kafka_name="$kafka_name" '(index($2,"master") == 1) || (index($2,"worker") == 1) || ( (kafka_name != "") && (index($2,kafka_name) == 1) )' file
23.1.22.155 kafka02.dfg.com
23.1.22.111 master01.dfg.com
23.1.22.239 master02.dfg.com
23.1.22.170 master03.dfg.com
23.1.22.167 worker01.dfg.com
23.1.22.165 worker02.dfg.com
23.1.22.112 worker03.dfg.com
答案 1 :(得分:2)
当 $kafka_name
为空时,模式为 "\smaster|\sworker|\s"
,最后一个选项匹配任何有空格的行,所以它匹配所有内容。
一种选择是将 $kafka_name
设置为您知道永远不会存在的内容而不是空字符串,例如
kafka_name=kafkaXXXX
另一种方法是仅当模式不为空时才将 $kafka_name
添加到模式中。
pattern="\smaster|\sworker"
if [ -n "$kafka_name" ]
then pattern="$pattern|\s$kafka_name"
fi
egrep "$pattern" /etc/hosts