linux三剑客

linux三剑客grep、sed、awk

正则表达式

正则表达式是定义的模式的模板,linux用它来匹配数据。如果数据匹配模式,则会接受进一步的处理。否则,不会进行处理。
正则表达式有两种引擎,引擎用来解释正则表达式和执行文本匹配。

  • BRE。基础。
  • ERE。拓展,包含更多的模式。
    在linux中,grep、awk、sed会使用正则表达式来匹配数据。

特殊字符

正则表达式有一些特殊字符有着特殊的含义,下面以sed工具进行说明。

> echo "book store" | sed -n '/^book/p'		#匹配book开头的行,-n表示用p代替命令输出,否则有两行数据,p表示输出匹配的模式。

.
==.==表示任意一个字符。

> echo "book store" | sed -n '/./p '
> echo "book store" | sed -n '/.o/p'	#使用一个字符串进行匹配,字符串的第一个字符随意,第二个一定是o

*
表示前面的字符或者字符组出现了0次或多次,==.*==两者连用 表任意多个字符。注意,这里的*与linux命令行中的*不一样!

> echo "book store" | sed -n '/o\*/'		#匹配0个或多个o字符
> echo "book store" | sed -n '/.\*'         #使用任意字符串进行匹配,即所有数据都能匹配

[]
字符组。若数据中出现该字符组的任一字符,则数据匹配该模式。例如[a,b,c]表数据中若含有abc中的任意一个都算匹配。
可以使用连续的区间而不用一个个的指定字符。如,[a-z],[0-9]。也可使用不连续的区间,如[1-35-6]表示区间[1-3]和[5-6]。另外,可以搭配==^==使字符组反转,例如[^1-2]表示除1或者2之外的字符。

> echo "123" | sed -n '/[4-6]/p'			#匹配含有4,5,6的行。这一行不匹配。
> echo "4" | sed -n '/\[2-3][5-6]/p'		   #匹配含有2,3,5,6的行。这一行不匹配。
> echo "3" | sed -n '/\[^1-2]/p'			#匹配不含1或2的行。

此外,正则表达式有一些特殊的字符组。

特殊字符组说明
[[:alpha:]]英文字母,同[a-zA-Z]
[[:alnum:]]任意字母和数字,同[0-9]或[a-z]或[A-Z]
[[:blank:]]空格或者制表符
[[:digit:]]数字
[[:lower:]]小写英文字母
[[:upper:]]大写英文字母
[[:print:]]可打印字符
[[:punct:]]标点符号
[[:space:]]任意空白字符,包括:空格、制表符、NL、FF、VT和CR

^
锚定符,表示行首。也可出现在==[]中,是[]==表示排除字符组。如,[^a]除a以外的字符。

echo “num1: hello” | sed -n ‘/^num1/p’ #匹配以num1开头的行

$
锚定符,表示行尾。与 ^ 结合得到 ^$,表示空行。在使用行号寻址的时,表示最后一行。

echo “hello” | sed -n ‘/^$/p’ #匹配空行
echo “what a big 3” | sed -n ‘/3$/p’ #匹配以3结尾的行

{}
花括号用于限定前面字符或者字符组出现的次数。有以下格式:

  • {n}。精确到n个。
  • {n,}。至少n个。
  • {n,m}。至少n个,至多m个。

使用花括号,需要ERE模式的引擎。若在sed中使用,需要转义

echo “this an book!” | sed -n ‘/o\{3\}/p’ #不会匹配,因为没有连续的3个o
echo “this an book!” | sed -n ‘/o\{2\}/p’ #匹配,含有连续的2个o

|
表示逻辑或,模式1==|== 模式2,表示若数据含有两个模式中的任意一个模式,就算匹配。在sed中使用需要转义

echo “you have a apple” | sed -n ‘/apple\|banana/p’ #管道符需要转义,匹配apple或者banana

+
前面字符或者字符组出现1次以上。注意转义。

echo “abc” | sed -n ‘/a\+/p’ #a出现一次,匹配
echo “bc” | sed -n ‘/a\+/p’ #a没有出现,不算匹配

?
前面字符或者字符组出现0次1次。注意转义。

echo “abc” | sed -n ‘/a\?/p’ #a出现一次,匹配
echo “bc” | sed -n ‘/a\?/p’ #a没有出现,也算匹配

()
==()==用于给表达式分组。注意转义。

echo “a = 1” | sed -n ‘/\(a\|b\) = /p’ #匹配
echo “b = 1” | sed -n ‘/\(a\|b\) = /p’ #匹配
echo “c = 1” | sed -n ‘/\(a\|b\) = /p’ #不匹配

grep

sed

sed称作流编辑器,它主要做了:

  1. 从输入中读取一行
  2. 根据所提供的模式匹配数据
  3. 根据命令修改数据
  4. 将新的数据写到stdout中。不管数据是否被修改,都会输出到标准输出。

sed命令的格式如下:

 > sed options script file   #options是选项;srcipt是命令,包好模式和命令;file是输入文件

以下是sed的一些常用的选项及其说明:

sed选项说明
-e script使用e指定多条命令
-f file使用f读取存放命令的文件
-n不输出数据,但可以使用命令p输出满足模式的数据
-i输出会写入源文件中

一般使用sed作为sed脚本文件的拓展名。

sed中的命令

寻址

sed支持两种寻址方式,使用文本模式寻址和使用行号寻址。可以在寻址后面加上==!==,对地址取反,让脚本作用于与该模式不匹配的行。
两种寻址方式的格式:

address command #对匹配的行执行一条指令
address { #对匹配的行执行多条指令
command1;
command2;、
command3;
}

在执行完一条命令或者一组命令后,会处理下一行。

使用行号寻址

> sed -n '1,5s/cat/dog/' data.txt  #替换1到5行中的首个cat为dog
> sed -n '1,$s/cat/dog/' data.txt  #替换所有行的首个cat为dog

使用文本模式寻址

> sed -n '/cat/s/cat/dog' data.txt  #替换 含有cat的行 的首个cat为dog

使用==!==对地址取反

> echo "dog mouse" |sed -n '/dog/p'   #会打印包含dog的行
> echo "dog mouse" | sed -n '/dog/!p'  #不会打印包含dog的行,它会匹配不包含dog的行

执行多条指令

> sed -n '1,$
> {
>	s/cat/dog/
>	s/dog/mouse
>}'                                          #对所有行执行多条指令
替换

替换命令 s/字符串/字符串/,会将满足模式中的行中一个字符串替换为另外一个字符串,默认只替换一次。为避免/和\造成的辨识不清楚,可以使用 ! 代替 /, 替换后,s!字符串!字符串!
替换命令默认只替换第一个满足模式的字符串,可以使用替换标记修改替换的行为。替换标记使用方法如下:

> sed 's/dog/cat/替换标记' data.txt

替换标记如下:

  • 数字。假设指定数字2,则替换满足条件的第2处字符串。
  • g。替换所有满足条件的字符串。
  • p。输出修改后的行。
  • w。将输出保存到指定的文件中。
删除

删除命令d会删除所有满足模式的行。可以使用行号、文本模式指定要删除的行,此外,也可以使用两个模式来删除两个模式之间的行。

> sed '/dog/d' data.txt  #删除含有dog的行
> sed '2d' data.txt         #删除第二行
> sed '/dog/,/cat/'         #删除dog和cat之间的所有行
插入和附加文本

插入命令i会在行前增加一个新行,附加命令a会在行后增加一个新行,字符串使用==\==指定。
使用格式如下:

> sed '[address] i \string' data.txt
> sed '[address] a \string' data.txt

如:

> sed '1 i\dog' data.txt              #在第一行前插入dog
> sed '1 a\dog' data.txt            #在第一行后插入dog
> sed '/cat/i\dog' data.txt        #在有cat的行的前面插入dog 
修改行

修改(change)命令c会修改它所匹配的行,使用==\== 指定修改后的字符串。命令c与命令s的区别在于,c会修改整行,而s只修改匹配的数据。
使用格式:

> sed '\dog\c/cat' data.txt   #将含有dog的行整体修改为字符串cat
转换

转换命令y用于处理单个字符。通过给定两个大小相同的集合,命令y可以将一个集合中的字符映射为另一个集合中的字符。
使用格式:

> [address]y/字符集s/字符集d/    #替换s中的字符为d中字符

如:

> sed '1,$y/dg/ab/' data.txt           #将满足模式的行中的d替换为a,将g替换为b
打印

可以使用三个指令用来打印数据。分别是:

  • p。打印完整的行。
  • =。打印行号,行号在行的上一行。
  • l。打印行中数据,不可打印数据使用一些字符来代替。
> sed '1,5p' data.txt  #打印1到5行
> sed '1,5=' data.txt  #打印1到5行的行号
> sed '1,5{=;p]}' data.txt  #先打印行号,再在下一行打印行中数据
> sed '1,5l'    data.txt   #打印行中数据,不可打印字符也会使用字符表示
处理文件

处理文件会使用两种命令,分别是命令r,和命令w。命令r将指定的文件数据插入到数据流中,而命令w则将数据流写入指定文件中。sed不会处理插入的数据。
使用格式如下:

> sed '[address]r file1' file2
> sed '[address]w file1' file2

> sed '1r data1.txt' data.txt   #将data1.txt中的数据插入到第一行的后面。
> sed '1w data1.txt' data.txt  #将data.txt的第一行数据写入data1.txt中。

进阶命令

多行数据

多行数据命令包括nNPD
命令n跳转到下一行接着执行脚本,命令N将下一行数据加入当前行然后接着执行脚本。命令PD是命令pd的多行版本,用于处理多行数据中的第一个数据。

命令n

> cat data.txt  #两行数据 
> dog
> cat

> sed -n '{
> n              #跳转到第二行
> p              #执行单行打印数据
> }' data.txt	#只会打印第二行数据

命令N

> sed -n '{
> N                     #将下一行数据加入当前模式空间
> p                     #打印两行数据,即打印“dog”和“cat”
> }' data.txt                   

使用命令N后,下一行数据加入到当前模式空间,和之前在模式空间的行当作一行来处理。注意,如果下一行没有数据,则命令N会执行失败从而完成sed

命令P仅会打印第一个行数据。
如:

> sed -n '{
> N                     #将下一行数据加入当前模式空间
> P                     #打印第一个行数据,即只打印“dog”                 
> }' data.txt           #打印两行数据

命令D
如果当前模式空间没有换行符,则命令D的作用与d一致。如果有换行符,则命令D会删除第一个换行符之前的字符包括换行符。并且,**不会读取新的行,而是从当前模式空间开始执行脚本。**这意味这命令N和命令D连用会形成一个循环,D之前的脚本会不停的执行直到文本数据末尾,而命令D后面的脚本不会再执行。
下面给出一个使用同时使用命令D和命令N的例子,该例子会将jack[ \n]ma替换为people[ \n]richer,如果jack ma只存在于一行中,只需简单的使用替换命令s就行,但jack ma可能分成两行存储。为了解决该问题,可以使用命令N和命令D,命令N将下一行加入当前行,之后可以替换跨行的jack ma,而使用命令D可以不断的迭代该过程。

> cat jack.txt
> jack ma,jack
> ma,jack
> ma
> jack ma
> 
> sed -n '{
>N
>s/jack\([\n ]\)ma/people\1richer/g  # ()和\1是模式替换,参考下文
>P                             #打印数据,只打印模式空间中第一行的数据
>D                             #执行D指令,若有换行,则删除一行,并迭代之前的命令
>}' jack.txt
保持空间(缓冲区)

sed使用了两类空间,第一种是模式空间,为当前脚本所工作的空间;另外一个是保持空间,它是一个缓存区。可以使用命令复制数据到缓存区,也可复制缓存区的数据回到模式空间

命令说明
h从模式空间复制到保持空间
H从模式空间附加到保持空间
g从保持空间复制到模式空间
G从保持空间附加到模式空间
x交换模式空间和保持空间的内容

注意以上操作要么是复制,要么是附加,不会删除数据。也就是说,如果将模式空间的数据复制到保持空间,当前脚本处理的仍旧是模式空间原有的数据。要想处理下一行的数据,要么使用n,要么使用N,要么等待当前脚本处理完当前的行。

控制流

bt
通过给定b一个地址可以让脚本跳转到特定的标签,如果没有指定标签,则跳转到脚本末尾,接下来会使用脚本处理下一行数据。
下面的命令会替换一行中的所有逗号,这也可以通过使用带替换标记g的替换命令来完成。

> echo "a,b,c,d,e" | sed -n '{
>	:start                  #标签
>	s/,/ /1p              #替换第一个逗号,并打印行
>	/,/b start          #有条件跳转。若行中存在逗号,则跳转到start处
>}'

使用命令b时需要给定终止条件或继续条件,否则会无限循环。

t会在命令替换中使用,若成功替换,则跳转到特定标签,否则继续执行接下来的指令。可以使用t完成上面的操作。

> echo "a,b,c,d,e" | sed -n '{
>	:start
>	s/,/ /1p
>	t start  #成功执行替换命令后,会跳转到start
>}'
模式替代

在替换指令s中,可以使用一些特殊字符替代匹配出的数据。特殊字符有 &\数字
==&==是完整的匹配数据的别名,假设有指令:

> sed '{s/ta[a,b]x/"&"/}'    #给匹配出的数据加上双引号

符号 & 代表了前面匹配出的数据,即taax或者tabx。由于匹配出的数据可能有多种,因此不能使用一个具体的字符串指代,sed使用了符号==&==指代匹配出的数据。

\数字用于指代匹配数据中的一部分,使用 () 标识要指代的数据,之后,使用 \1指代第一个, \2指代第二个,其他以此类推。
例如:

> echo "a+b a-b" | sed -n '{s/a\([+-]\)/a"\1"b/g;p}'  #原括号需要转义,\1指代前面的+和-,该指令给给+和-加上双引号

awk

awk有多个版本,这里介绍gawk版本的使用方法。gawk是一种格式化输入输出文本文件的工具,它读入具有格式的文本,然后加以处理后输出。
它提供了如下功能:

  1. 可以定义变量保存数据。可以在awk内定义变量,之后可以使用这些变量。
  2. 结构化编程。提供了if、while、for、do-while等结构编程所需要的方法。
  3. 可以提取出数据元素中的各个数据,处理后然后输出。通过记录分隔符分割数据得到记录,然后使用字段分隔符分割字段得到各个字段,这些字段的值赋予到各个内建变量上。
  4. 可以使用数学计算和字符串操作来修改数据,这可以通过使用内建数学函数、内建字符串函数或者自定义函数完成。

gawk使用格式

使用格式

$ gawk 'BEGIN{} {} /pattern/{} $1 ~ /pattern/{} $1 !~ /pattern/{} END{}'

正则
在gawk中,可以使用正则匹配记录,若匹配成功,则会执行后面的代码段。

$ gawk '/richer/{print "it has money"}'   #如果记录中有richer,则打印信息

BEGIN与END
BEGIN和END是两个关键字,用于声明在脚本开始执行和执行完毕后,要执行的代码段。

$ gawk 'BEGIN{print "file begin"} END{print "file end"}'

波浪符==~==
波浪符用于在一个字段中使用正则匹配数据,可以使用感叹号==!==对正则取反。

$ gawk '$1 ~ /1/{print $0}'    #如果第一个字段存在1,则打印记录
$ gawk '$2 !~ /2/{pritn $0}'   #如果第二个字段不存在2,则打印记录

gawk常用的选项

选项说明

变量

变量有两种类型:自定义变量和内建变量。自定义变量没有类型,直接定义即可,在gawk中,还可以定义数组,数组索引为字符串。内建变量也有两类:一类用于设置处理输入输出的相关参数,另外一类则包含了环境的一些信息。

自定义变量

脚本中定义变量
直接定义,没有类型

$ gawk '{val = 1;print val}'

注意,获取变量的值不使用美元符。
命令行中定义变量
可以直接定义变量,也可以使用选项==-v==后定义变量。

$ gawk -v val=2 'BEGIN{print val}'   #-v指在BEGIN之前定义变量
$ gawk val=2 'BEGIN{}'               #在BEGIN内无法使用命令行定义的变量

数组
索引可以为字符串。

gawk 'BEGIN{val["a"] = 1;val["b"] = 2}'
内建变量

gawk会将输入的数据切割成记录,然后再将记录切割成字段。切割方式默认是以换行切换数据得得记录,以空格切割记录得到字段。也可通过在BEGIN或者命令行中设置一些选项来改变这一默认行为。另外,gawk不仅可以用字符分割,也可直接指定每个段的长度。
字段与记录相关选项

选项说明
FIELDWIDTHS用逗号分割的一串数字,每个数字为各段长度,不使用字符切割
FS输入字段分隔符
RS输入记录分隔符
OFS输出字段分隔符
ORS输出记录分隔符

数据变量
包含一些环境信息。

变量名说明

结构化编程

if

if( condition ){
  statments        #没有分号;
}else{
  statments
}

for
两种形式,c形式和类似shell的形式。

#c形式
for(i=0; i<10; ++i)
{
  statment  
}
#类shell
for(var in array){			#有括号
  statments 		
}

while

while ( condition ){
  statment
}

do-while

do{
  statment
}while(condition)

函数

打印函数

格式化打印
类似c语言,也有控制宽度、小数点位数和控制左对齐的功能

gawk '{
print %-3.5f        #宽度为3,小数点后5位,左对齐
}'
自定义函数

定义格式

function func([varibales])
{
  statements
}

在定义函数的时候,函数必须出现在所有代码块(包括BEGIN)的前面。
函数也可以定义在一个文件中,gawk可以使用-f参数使用该文件中的函数。

内建函数

数学函数

字符串函数

时间函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux三剑客是指在Linux系统中经常使用的三个命令行工具,分别是grep、awk和sed。 首先是grep命令,它是Global Regular Expression Print的缩写,用于在文件中查找匹配某一模式的行。grep命令的基本语法是"grep [选项] 模式 文件",可以使用各种选项来处理不同的需求。grep命令的应用非常广泛,常用于检索文件内容、过滤日志、查找错误等,通过使用正则表达式,可以实现更高级的搜索。 其次是awk命令,它是一种文本处理语言,经常用于对文本文件进行分析和处理。awk命令的语法是"awk '条件 动作' 文件",其中条件是用于选择匹配的行,动作是对匹配的行执行的操作。awk命令可以方便地进行字段提取、计算、格式化输出等操作,特别适合处理结构化的文本数据。 最后是sed命令,它是Stream Editor的缩写,是一种基于行的文本处理工具。sed命令的基本语法是"sed [选项] '动作' 文件",其中动作是对每一行执行的操作。sed命令可以进行文本的增删改查等操作,如替换、删除、插入等,可以通过正则表达式实现复杂的模式匹配和替换。 Linux三剑客Linux系统中非常重要的命令行工具,它们的灵活性和强大功能使得我们可以方便地对文本文件进行操作和处理。无论是开发、运维还是日常使用,熟练掌握grep、awk和sed命令都对提高工作效率和解决问题非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值