详解流编辑器 sed 和 编程语言 awk

一、流编辑器 sed

sed 是一个精简的、非交互式的流式编辑器,它在命令行中输入编辑命令和指定文件名,然后在屏幕上查看输出。

逐行读取文件内容存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。原文件内容并没有改变。

(一)sed 简单用法

选项

-e

连接多个编辑命令(直接在命令行模式上进行sed的操作)

-f

指定sed脚本文件名(将sed的操作写在一个文件里,用的时候 -f filename 就可以按照内容进行sed操作了)

-n

阻止输入行自动输出(只有经过sed处理过的行才显示出来,其他不显示)

-r                                 使之支持扩展正则表达式

                                                  -i                                  后跟文件名,sed 的操作会更改到文件

sed ‘4,$d’ test.in   sed ‘3q’ test.in sed ‘s/public/PUBLIC/’ test.in sed -n ‘s/public/PUBLIC/p’ test.in

指定多个命令的三种方法:

1、用分号分隔命令 sed 's/public/PUBLIC/;s/north/NORTH/' test.in 

2、每个命令前放置-e sed -e 's/public/PUBLIC/' -e 's/north/NORTH/' test.in

3、使用分行命令功能,在输入单引号后按return键就会出现多行提示符(>) sed ' > s/public/PUBLIC/ > s/north/NORTH/' test.in

在脚本中使用sed命令:

test.sed文件内容如下: s/public/PUBLIC/ s/north/NORTH/

sed -f test.sed test.in

(二)sed 命令语法

sed_cmd:使用格式:[address]  sed_edit_cmd(通常用单引号括起来),其中address为sed的行定位模式,用于指定将要被 sed编辑的行。如果省略,sed将编辑所有的行。sed_edit_cmd为sed对被编辑行将要进行的编辑操作。

sed_cmd中address的定位方式:

n

表示第 n 行

$

表示最后一行

m,n

表示从第 m 行到第 n 行

/pattern/

查询包含指定模式的行。如 /disk/、/[a-z]/

/pattern/,n

表示从包含指定模式的行 到 第 n 行

n,/pattern/

表示从第 n 行 到 包含指定模式的行

/模式1/,/模式2/

表示从包含模式1 到 包含模式2的行

反向选择,如 m,n!的结果与m,n 相反

(三)常用的sed_edit_cmd:

(四)常用sed编辑命令小结

q:退出,读取到指定行后退出 sed。

sed  '3q' test.in

p

打印匹配行

s

替换命令

=

显示匹配行的行号

l

显示指定行中所有字符

d

删除匹配的行

r

读文件

a\

在指定行后面追加文本

w

写文件

i\

在指定行前面追加文本

n

读取指定行的下面一行

c\

用新文本替换指定的行

q

退出 sed

二、编程语言awk

awk 是一种用于处理数据和生成报告的编程语言

awk 可以在命令行中进行一些简单的操作,也可以被写成脚本来处理较大的应用问题

awk 与 grep、sed 结合使用,将使 shell 编程更加容易

Linux 下使用的awk 是gawk

awk 逐行扫描输入 (可以是文件或管道等),按给定的模式查找出匹配的行,然后对这些行执行awk 命令指定的操作。

与 sed一样,awk不会修改输入文件的内容。

可以使用重定向将awk的输出保存到文件中。

(一)awk简单用法

用法示

选项

-F

指定输入记录字段的分隔符,默认使用环境变量IFS的值

-f

从指定文件读取awk_script

-v

为awk设定变量

The IFS is a special shell variable. You can change the value of IFS as per your requirments. The Internal Field Separator (IFS) that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is <space><tab><newline>. You can print it with the following command: cat -etv <<<"$IFS" IFS variable is commonly used with read command, parameter expansions and command substitution.

awk -F: '{ print $1 }' /etc/passwd

awk -F: '{ print $1, $3 }' /etc/passwd   // 输出以空格连接

awk -F: '{ print $1 "|" $3 }' /etc/passwd  // 输出以 | 连接

awk -F: '/root/{ print $1 "|" $3 }' /etc/passwd

awk -F: '/^root/' /etc/passwd   // 开头是root 的行

(二)awk_script语法

注意BEGIN和END都是大写字母

awk  'BEGIN {actions}

/pattern1/{actions}

      ......

     /patternN/{actions}

     END {actions}'  input_file

其中BEGIN{actions}和 END{actions}是可选的

awk_script 可以由一条或多条 awk_cmd 组成,每条 awk_cmd 各占一行。

每个 awk_cmd 由两部分组成:/pattern/{actions}

awk_cmd 中的 /pattern/ 和 {actions} 可以省略,但不能同时省略;/pattern/ 省略时表示对所有的输入行执行指定的 actions;

{actions} 省略时表示打印整行。

(三)awk 的执行过程

取出ip 地址:

ifconfig | awk '/inet addr/{ print $2 }' | awk -F: '{ print $2 }'

ifconfig | awk '/inet addr/{ print $2 }' | awk -F: 'BEGIN { print "begin..."} { print $2 } END { print "end..."} '

(四)模式匹配

① 使用正则表达式:/rexp/,如/^A/、/A[0-9]*/

^

只匹配行首 ( 可以看成是行首的标志 )

$

只匹配行尾 ( 可以看成是行尾的标志 )

*

一个单字符后紧跟 *,匹配 0个或多个此字符

[ ]

匹配 [] 内的任意一个字符 ([^]反向匹配 )

\

用来屏蔽一个元字符的特殊含义

.

匹配任意单个字符

str1|str2

匹配 str1 或 str2

+

匹配一个或多个前一字符

?

匹配零个或一个前一字符

( )

字符组

(五)字段分隔符、重定向和管道

NR表示从awk开始执行后,按照记录分隔符读取的数据次数,默认的记录分隔符为换行符,因此默认的就是读取的数据行数,

NR可以理解为Number of Record的缩写。

在awk处理多个输入文件的时候,在处理完第一个文件后,NR并不会从1开始,而是继续累加,因此就出现了FNR,

每当处理一个新文件的时候,FNR就从1开始计数,FNR可以理解为File Number of Record。

NF表示目前的记录被分割的字段的数目,NF可以理解为Number of Field。

(六)更多awk

awk不仅是一个命令,它更是一个编程语言 变量 内部变量      awk ' {print NR,$0} ' #给文件加上行号 自定变量 函数 内置函数 自定义函数      awk '{ print sum($1,$2) } function sum(x,y) { s=x+y ; return s }' grade.txt 数组      awk 'BEGIN { print split("123#456",arr,"#") ; for (i in arr) { print arr[i] } }'  // arr: 123 456

result="id 10 28 19 32"

data=(`echo $result | awk '{ for(i=2;i<=NF;i++) {print $i}}'`)

for task_id in ${data[@]}

do

done

参考: 《鸟哥的Linux私房菜基础篇》 《高级bash shell编程指南》

http://www.grymoire.com/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏xingoo, 一个梦想做发明家的程序员

《vi和vim》 学习手记(2)

:set wm=10 设置与右边界的距离。右边界为10个字符。 o 移到一行的开头 s 移到一行的结尾 w 移到下一个单词的 b 退后一个单词 S 更改一行文本...

1828
来自专栏游戏杂谈

php的Snoopy类

获取请求网页里面的所有链接,直接使用fetchlinks就可以,获取所有文本信息使用fetchtext(其内部还是使用正则表达式在进行处理),还有其它较多的功能...

1073
来自专栏生信小驿站

R语言基础操作①基础指令

q()——退出R程序 tab——自动补全 ctrl+L——清空console ESC——中断当前计算

2472
来自专栏练小习的专栏

border的transparent与rgba(0)的区别是什么?

在用after和before做一个小的tips箭头的时候,发现一个很蛋疼的问题,boeder写成transparent和写成rgb(x,x,x,0),在webk...

18210
来自专栏Java编程技术

伪共享

计算机系统中为了解决主内存与CPU运行速度的差距,在CPU与主内存之间添加了一级或者多级高速缓冲存储器(Cache),这个Cache一般是集成到CPU内部的,所...

743
来自专栏javathings

volatile 解决了什么问题?

volatile 关键字是最常问到的问题,关于这个关键字的作用解释,网上的文章已经多如牛毛了。

1603
来自专栏数据结构与算法

namespace用法

一直不知道namespace怎么用,所以在noip吃了不小的亏,然后前天的省选模拟写了四个子程序,拼的我心累QWQ... 今天膜了一下mjt大佬,get到了新姿...

2825
来自专栏软件开发 -- 分享 互助 成长

C++ STL之deque的基本操作

前两篇博文中已经介绍了vector和list的两种容器,我们发现他们各有各的优缺点,vector在内存中连续存储,支持随机访问,但是查找和删除的效率比较低,而l...

2005
来自专栏Hongten

python开发_python中的module

在python中,我们可以把一些功能模块化,就有一点类似于java中,把一些功能相关或者相同的代码放到一起,这样我们需要用的时候,就可以直接调用了

884
来自专栏北京马哥教育

10分钟学会 linux awk命令

? 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读...

4109

扫码关注云+社区