一个获取ip地址的命令详解

今天在看师兄写的一个安装脚本文件,虽然之前学了不少bash知识。不是太熟练,打算练练手,可是这个命令折磨了我好久。索性花点时间把它弄清楚。awk这个工具语言的难度,我是体会到了。写正则表达式的都是什么人啊。。。佩服!!!

标题:一个获取ip地址的命令详解,涉及awk知识和gensub函数:

1、先上命令

MyIpAddr=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}'|head -1)

1.1、先看下它得出的结果吧:

一个获取ip地址的命令详解_第1张图片在这里插入图片描述

  • 就是这个命令,折磨了我很久。我们来思考它是怎么获取到你的主机IP地址的?反向推理一波,一边猜测,一边解题。。。

1.2、我们先来拆分下这个命令:

  • 拆分是为了帮助我们更好的化繁为简,其他的命令我就不解释了。主要围绕awk和gensub这两个进行解释。
ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}'|head -1
awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}'

2、awk和genden函数的解释

2.1、awk命令解释,擅长列输出。awk的一般语法格式为:

一个获取ip地址的命令详解_第2张图片

awk [-参数 变量] 'BEGIN{初始化}条件类型1{动作1}条件类型2{动作2}。。。。END{后处理}'
  • pattern+action
条件类型1是/^[0-9]+: /,你要知道正则表达式要写在/ /双斜杠这个里面。那么他是用一个正则表达式来作为一个条件类型。动作1是{},里面是空的。
继续...
条件类型2是/inet.*global/,动作2是{print gensub(/(.*)\/(.*)/, "\\1", "g", $2)},他用这个print加上gensub函数作为动作。
关于这个分号;  分号只是起到一个分隔作用,表示分号前和分号后没有联系。

2.2、gensub函数命令解释:

gensub(a,b,c[,d])全局替换,匹配正则表达式a, 用b替换,c为指定替换目标是第几次匹配(“g”:表示全局替换),d为指定替换目标是哪个域如$1,$2,若无d指$0,返回值为target替换后内容(未替换还是返回target原内容)与sub、gsub不同的是,target内容替换后不变。

2.3、简单测试下,帮助更好的了解命令干了什么,之后反推下:

  • 我们先用pattern1来测试下匹配,可以看到得到了两个网卡信息:
    一个获取ip地址的命令详解_第3张图片
  • 继续看下图,继续做一个pattern2的匹配看下:

一个获取ip地址的命令详解_第4张图片

  • 可以看到里面有我们最终的ip地址了,那么之后就是action2里面的print和gensub的事了。
  • gensub(/(.*)\/(.*)/, "\\1", "g", $2)那么这个到底是干了什么呢?
  • 之前我提到了gensub的函数命令解释,那么可以推测gensub就是把IP地址从下面图中的句子里提炼出来:
    在这里插入图片描述

我们再来对genden做一个详细的解释:

  • (.*)\/(.*) 这个的意思是 括号1/括号2,括号里面有两个一模一样的正则表达式。匹配出了192.168.3.11/24
  • “//1”表示引用第一个括号例匹配的内容,也就是192.168.3.11,用它来替换,也就是192.168.3.11/24变成了192.168.3.11
  • “g”表示全局替换。
  • $2表示第二个域。其中inet是第一个域里面,192.168.3.11在第二个域里面,brd在第三个域里面。。。

你可以尝试将

MyIpAddr="inet 192.168.3.11/24 brd 192.168.3.255 scope global"
echo ${MyIpAddr} >> test1.txt
awk '{print gensub(/(.*)\/(.*)/,"\\1","g",$2)}' test1.txt
  • 多做几次试验。。。

后记:

  • ^[0-9]+表示匹配输入字符串开始的位置,匹配多个数字。 ^ 为匹配输入字符串的开始位置。[0-9]+匹配多个数字, [0-9] 匹配单个数字,+ 匹配一个或者多个。
  • runoo*b可以匹配 runob、runoob、runoooooob 等,* 号代表字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。

你可能感兴趣的:(一个获取ip地址的命令详解)