玩转Linux - 神级工具 sed & awk
sed和awk是Linux高手们必备的技能,很值得我们去研究的东西。...
简介
本文主要介绍 Linux 系统的两个神级工具:sed 和 awk ,他们是Linux高手们必备的技能,很值得我们去研究的东西。这里是我在网上书上收集的相关资料,因为这两个工具很有名也很重要,所以这些资料会帮助我更好的了解和熟悉它们。
什么是sed
在《sed and awk》一书中(1.2 A Stream Editor)的解释是:Sed本质上是一个编辑器,但是它是非交互式的,这点与VIM不同;同时它又是面向字符流的,输入的字符流经过Sed的处理后输出。这两个特性使得Sed成为命令行下面非常有用的一个处理工具。
Sed本身是一个管道命令,可以分析 standard input 的,主要是用来分析关键字的使用、统计等,此外还可以将数据进行替换、删除、心中、选取特定行等功能。
基本概念
sed命令的语法如下所示:sed [-nefr] [动作]
参数说明:
- -n : 使用安静模式,一般所有来自STDIN的数据会被列出到屏幕上,但是 -n 在可以只列出经过 sed 处理过的那一行。
- -e : 直接在命令行模式上进行 sed 的动作编辑。
- -f : 直接将 sed 的动作卸载一个文件内, -f filename 则可以执行 filename 内的 sed 动作。
- -r : sed 的动作支持的是扩展型正则表达式的语法(默认是基础正则表达式语法)。
- -i : 直接修改读取的文件内容,而不是由屏幕输出。
n1,n2:不见得会存在,一般代表选择进行动作的行数。动作说明: [n1],[n2] function
举例来说:如果我的动作是需要在 10 到 20 行之间进行的,则“10,20[动作行为]”
function 有下面这些参数:
- a:新增,a 的后面可以接字符串,而这些字符串会在新的一行出现(目前的下一行)。
- c:替换,c 的后面可以接字符串,这些字符串可以替换n1,n2之间的行!
- d:删除,因为是删除,所以 d 后面通常不接任何参数。
- i:插入,i 的后面可以接字符串,而这些字符串会在新的一行出现(目前的上一行)。
- p:打印,也就是将某个选择的数据打印出来,通常 p 会与参数 sed -n 一起运行。
- s:替换,可以直接进行替换工作。通常这个 s 的动作可以匹配正则表达式!例如:1,20s/old/new/g 就是。
关于 sed 的一些常见使用
以行为单位的新增或删除功能
案例(一)nl /etc/passwd | sed '2,5d'说明:
- sed 的动作为 ‘2,5d’,那个 d 就是删除,命令运行的效果就是把2~5行给删除。
- 需要注意的是,原本应该是要执行 sed -e 才对,没有 -e 也行。
- 另外还需要注意的一点:sed 后面接的动作,请务必要以 ‘’ 两个单引号括住。
- 如果你只想删除第二行,那么命令就是:nl /etc/passwd | sed ‘2d’。
- 如果你想删除第三行到最后一行,那么就可以这么写:nl /etc/passwd | sed ‘3,$d’
案例(二)
nl /etc/passwd | sed '2a drink tea'说明:
- 命令执行的效果就是在第二行后面(也就是第三行)加上“drink tea”字样。
- 如果你想在第二行前面加上字符串,那么你可以这样:nl /etc/passwd | sed ‘2i drink tea’
案例(三)
nl /etc/passwd | sed '2a drink tea or ......说明:
drink beer'
- 上面的命令的执行效果是在第二行后面加入2行字。
- 在每一行的后面必须要以反斜杠 来进行新行的增加。
以行为单位的替换与显示功能
案例(一)nl /etc/passwd | sed '2, 5c No 2-5 number'说明:
- 上面的命令的执行效果是将第2~5行的内容替换成“No 2-5 number”
nl /etc/passwd | sed -n '5,7p'说明:
- 上面的命令执行的效果是仅列出文件中的第5~7行的内容。
- 命令中的 -n 代表的是安静模式!但是这个参数建议加上。
sed 's/要被替换的内容/新的内容/g'说明:
- 以上命令执行的效果就是替换掉指定内容。
第一步:先查看源信息,利用 /sbin/ifconfig 查询 IP。
/sbin/ifconfig eth0注:我们的目的是要获得IP数据,那么先利用关键字找出那一行。
第二步:利用关键字配合 grep 选取出关键的一行数据。
/sbin/ifconfig eth0 | grep 'inet addr'注:因为只需要IP数据,所以接下来就是把不需要的内容都删掉,那么就需要一个正则表达式来帮助实现:
^.*inet addr:第三步:将 IP 前面的部分予以删除
/sbin/ifconfig eth0 | grep 'inet addr' |注:上面的命令就把 IP 前面的数据删掉了,那么接下来就是把 IP 后面的数据也删掉,此时的正则表达式则是:
sed 's/^.*inet addr://g'
Bcast.*$第四步:将 IP 后面的部分予以删除
/sbin/ifconfig eth0 | grep 'inet addr' |这样就能把 IP 截取出来了~~~
sed 's/^.*inet addr://g' | sed 's/Bcast.*$//g'
案例(五)
这里主要是展示 sed 与正则表达式的配合使用。假设我想在一个文件(你自己新建或者已有的,主要是测试而已)获取MAN字样的那几行数据,但是#在内的批注我不需要,而且空白行也不要。
第一步:先使用 grep 将关键字 MAN 所在行取出来。
cat /home/man.config | grep 'MAN'第二步:删除掉批注之后的数据。
cat /home/man.config | grep 'MAN' | sed 's/#.*$//g'第三步:那么接下来就是把空白行删除掉。
cat /home/man.config | grep 'MAN' | sed 's/#.*$//g' |
sed '^$/d'
直接修改文件内容(慎重)
首先要特别提醒的是,要练习 sed 修改文件内容的时候不能用任何系统配置文件,最好是自己新建一个测试文本来测试练习。案例(一)
sed -i '/s.$/!/g' test.txt说明:
- 上面命令执行效果是利用 sed 将test.txt内的每一行结尾为“.” 的换成 !
- 命令中的 -i 参数可以让你的 sed 直接去修改后面接的文件内容,而不是由屏幕输出。
案例(二)
sed -i '$a # This is a test' test.txt说明:
- 上面命令执行的效果是利用 sed 直接在test.txt最后一行加入 “This is a test”。
- 由于 $ 代表的是最后一行,而 a 的操作是新增,因此该文件最后新增。
什么是 awk
简单来说,awk 是一个数据处理工具。相比于 sed 常常作用于一整行的处理,awk 则比较倾向于将一行分成数个“字段”来处理。因此,awk 相当适合处理小型数据的数据处理。
对于编程语言来讲,awk 是一种便于使用且表达能力强的程序设计语言,可应用于各种计算和数据处理任务。
基本概念
基本语法awk '条件类型1{动作1} 条件类型2{动作2} ...' filename
- awk 后面接两个单引号病加上大括号{}来设置想要对数据进行的处理动作。
- awk 可以处理后续接的文件,也可以读取来自签个命令的 standardoutput。
- 如前面说的,awk 主要是处理每一行的字段内的数据,而默认的字段的分隔符为空格键或者[tab]键。 比如:
last -n 5 // 仅取出登陆者的数据前五行(last 可以将登陆者的数据取出来)如果我还要在这些信息中取出:账号与登陆者的IP,且账号与IP之间以[tab]隔开,那么可以这么改命令:
last -n 5 | awk '{print $1 "上面是 awk 最常使用的动作,通过 print 的功能来讲字段的数据列出来,字段的分割则以空格键或者[tab]按键来隔开。
" $3}'
上面的例子中,在每一行的每个字段都是有变量名称的,那就是2等变量名称。
备注:$1 指的就是第一列,但是 $0 则是代表一整行(第一行)。
上面的例子中整个awk的处理流程:
- (1)读入第一行,并将第一行的数据填入1,$2等变量中;
- (2)依据条件类型的限制,判断是否需要进行后面的动作;
- (3)昨晚所有的动作与条件类型;
- (4)若还有后续的“行”的数据,则重复上面1~3的不知,直到所有的数据都读完为止。
对于上面的案例指令 last -n 5 … 来讲,有几点需要注意的:注:awk是以行为一次处理的单位,而以字段最小的处理单位。
- 列出每一行的账号(就是$1)。
- 列出目前处理的行数(那就是 awk 内的 NR 变量)。
- 并且说明,该行有多少个字段(就是 awk 内的 NF 变量)。
last -n 5 | awk '{print $1 "
lines: " NR "
lines: " NR "
columes: " NF}'
awk的一些常见使用
awk 的运算符
- 大于: >
- 小于: =
- 小于或等于: =2以后处理)。
cat test.txt |说明:
awk 'NR==1{printf "s s s s s
",$1,$2,$3,$4, "Total" }
NR>2{total = $2 + $3 + $4
printf "s d d .2f
", $1, $2, $3, $4, total}'
- 所有 awk 的动作(即在{}内的动作),如果有需要多个命令来辅助是,可利用分号“;”间隔,或者直接以[Enter]按键来隔开每个命令,上面则是摁了三次。
- 逻辑运算中,如果是“等于”的情况,则务必使用两个等号“==”!
- 格式化处输出时,在 printf 的格式设置当中,务必加上 n ,才能实现分行。
- 与 bash 、shell 的变量不同,在 awk 当中,变量可以直接使用,不需要加上 $ 符号。
原文链接:https://segmentfault.com/a/1190000005720358
马哥Linux运维推出服务号啦!需扫描二维码!
获取更多服务,长按扫描下方的二维码,你懂得!
马哥Linux,智者的选择
☀ 马哥教育历经近10年发展,已成为面向企业级资深运维工程师、架构师的专业集训营式高端就业Linux培训学院。凭借多年良好口碑,其已经成为业内知名互联网公司重要人才战略合作伙伴,获得了百度、腾讯、阿里、大众点评、51CTO、唯品会、京东、中移动、新浪、红帽等互联网巨头的合作支持。毕业学员平均薪资达10K以上,累计受益人员达百万+。
☀ 咨询电话:400-080-6560☀ 官方站点:www.magedu.com
☀ 官方博客:www.178linux.com
关注 马哥Linux运维
微信扫一扫关注公众号