三剑客基础详解

作者 : 开心源码 本文共8064个字,预计阅读时间需要21分钟 发布时间: 2022-05-13 共195人阅读

三剑客基础详解

[TOC]

三剑客之grep详解

通配符与正则表达式这两口子可以说贯穿三剑客始终,甚至时贯穿linux始终,这样说,我觉得并不夸张。因而在写三剑客之前,先捋一捋这些这些知识点就很有必要了。

相对而言正则用于三剑客多少量,通配符用于Linux命令行多少量。

1.通配符

通配符形容
*任意多个字符
任意单个字符
.当前目录
..上级目录
命令分隔符
~当前客户家目录
$引用变量
!逻辑运算非
&&前一个命令执行成功,则执行后面的命令
||当前命令执行失败,则执行后面命令
单引号,原样输出,所见即所得
双引号,可以置换变量的值,不加引号相当于双引号
`反引号中的内容会被优先解析
之前所在路径
{}shell脚本命令组合;命令行中内容序列
>重定向覆盖
>>重定向追加

2.基础正则

  • 锚定行首,如word表示以word开头的行
  • 锚定行首,如word表示以word结尾的行
  • ^$则表示空行
  • . 任意单个字符
  • *匹配其前面字符任意屡次
  • .*表示匹配所有字符
  • \ 转义字符,使得特殊字符失去特殊含义
  • []匹配范围内的单个字符
  • [^]匹配范围外的单个字符
  • 指定匹配次数的范围,即分组
    1. \{n,m\} 匹配前面字符n到m次
    2. \{n,\} 匹配前面字符至少n次
    3. \{,m\}匹配前面字符至多m次
    4. \{n\} 匹配前面字符n次

在扩展正则中可以去掉转义符,即egrep 或者者 grep -E

3.grep 讲解

3.1语法格式

grep [OPTIONS] [PATTERN] [FILE..]

grep [选项] [过滤的内容] [源文件]

3.2常用参数

  • -n 显示过滤内容所在行数
  • -o 只显示匹配到的内容,不会按行输出
  • -i 忽略大小写
  • -v 反向选择,显示未匹配到的内容
  • -E 支持拓展正则
  • -A 匹配到的行后面几行,即After
  • -B 匹配到的行前面几行,即Before
  • -C 配到的行前后几行,即context上下文
#准备好试验内容randolf@localhost:~/test $ ls && cat sed2.txt inittab  sed2.txt  test.md5  test.txtOh/my/god,dear me!hello wordyou are so cutewhat do you think of the partyI am so glad to tell you that I am crazy about Linux!Linux is better than Windows much more.#显示以hello开头的行,并且显示其所在行数randolf@localhost:~/test $ grep -n "^hello" sed2.txt 2:hello word#显示以cute结尾的行,并且只打印匹配到的内容randolf@localhost:~/test $ grep -o "cute$" sed2.txt cute#显示不包含单词you的行randolf@localhost:~/test $ grep -v "you" sed2.txt Oh/my/god,dear me!hello wordLinux is better than Windows much more.

4.拓展正则

  1. + 重复匹配前面字符1次及1次以上(区别于*匹配0次至屡次)
  2. ? 重复匹配前面字符0次或者者1次(.表示任意一个字符,不是匹配)
  3. | 可以同时过滤多个字符
  4. () 分组过滤,向后引用(也叫方向引用),将组中的内容作为一个整体来匹配,突破了只能匹配前面单个字符的限制,常常结合分组的使用
#新建测试文本testrandolf@localhost:~/test $ cat > test<<EOF> gods> gds> goods> gooods> goads> EOF#分别演示+ ? . 的用法randolf@localhost:~/test $ egrep "go?ds" test godsgdsrandolf@localhost:~/test $ egrep "go+ds" test godsgoodsgooodsrandolf@localhost:~/test $ egrep "go.ds" test goodsgoads#演示 | 的多字符过滤randolf@localhost:~/test $ egrep "gds|goods" test gdsgoods#向后引用结合分组的演示randolf@localhost:~/test $ echo "goodsgoods" >> testrandolf@localhost:~/test $ grep -E '(goods){2}' test goodsgoods

5.POSIX字符类

括号类含义
[:alnum:]字母数字字符
[:alpha:]字母字符
[:digit:]数字字符
[:graph:]非空白字符(非空格、控制字符等)
[:lower:]小写字母
[:print:]与[:graph:]类似,但是包含空格字符
[:punct:]标点字符
[:upper:]大写字母
[:xdigit:]允许十六进制的数字
[:cntrl:]控制字符

字符类用的较少,放在这里仅作备用

三剑客之sed讲解

sed全称为Stream Editor即流编辑器,用于过滤和转换文本,常用的功能包括增删改查,过滤,取行。

1.sed的执行流程

sed作为流编辑器仅支持单行操作,每次启动sed进程时,linux会为它在内存中单独分配一个专属的空间,我们称其为模式空间。sed每次只读取文本中的一行到模式空间中,执行完指定的sed内置命令后,默认将模式空间中的文本打印到屏幕上,而后删除模式空间中的文本,再读取原文本中的第二行,重复上面的操作,直至文本的最后一行。

sed1

2.语法格式

sed [option] [AddressCommand] [input-file]

2.1option:

  • -n 静默模式
  • -i 编辑原文件
  • -r 支持拓展正则

2.2 Address:

这里的地址我们指sed所挑选的目标行,支持模式匹配,即便用通配符等。

地址表示形式形容
1操作第1行
1,3操作第1到3行
1,+3操作第1行以及后面3行(1到4行)
1,$操作第1行到最后一行
1~2通用(nm),从第n行开始,步进为进行m挑选,如12表示第1、3、5….行

以上地址表示皆支持模式匹配,如

地址表示形式形容
/word/操作所有匹配到word这个单词所在行
/word/,/Linux/操作匹配到word的行一直到匹配到Linux的行,遵循懒汉模式的搜索匹配
/word/,+3操作匹配到word的行以及后面三行(从第一次匹配到word开始)
/word/,$操作匹配到word的行一直到最后一行(从第一次匹配到word开始)

懒汉模式匹配:第一次搜索到的结果(word)作为开始,并且第一次搜索到的结果作为(Linux)作为结尾

2.3 Command

此处命令指的是sed编辑器的内置命令,而不是linux的系统命令

现在创立如下文件touch /home/randolf/test/sed.txt

并且写入内容,作为试验文本:

cat >sed.txt<<EOF>0.I am the whole word>1.hello word>2.you are so cute>3.what do you think of the party>4.I am so glad to tell you that I am crazy about Linux!>5.Linux is better than Windows much more.>EOF

地址表示形式与命令的搭配太多不可能逐个演示,下面选取典型场景,为大家演示

  • p 打印行

    #打印第2到3行randolf@localhost:~/test $ sed '2,3p' sed.txt0.I am the whole word1.hello word1.hello word2.you are so cute2.you are so cute3.what do you think of the party4.I am so glad to tell you that I am crazy about Linux!5.Linux is better than Windows much more.

    咦?怎样打印这么多东西。我明明只选取2到3行呀。还记得上面说的嘛,“执行完指定的sed内置命令后,默认将模式空间中的文本打印到屏幕上”,没错,sed除了将我们选取的内容打印一遍,还没有不记得自己原本的职责,即打印一遍模式空间中的内容。所以就看了以上打印内容,2到3行打印了两遍。那假如不想要sed默认打印模式空间咋办?真相只有一个!选项-n,他表示静默模式,即不再默认打印模式空间中的内容,试试看喽。

    randolf@localhost:~/test $ sed -n '2,3p' sed.txt1.hello word2.you are so cute#顿时清新多了,舒服
    #打印匹配到word的行一直到匹配到Linux的行,遵循懒汉模式的搜索匹配randolf@localhost:~/test $ sed -n '/word/,/Linux/p' sed.txt 0.I am the whole word1.hello word2.you are so cute3.what do you think of the party4.I am so glad to tell you that I am crazy about Linux!

    比照原来的文本中,含单词word的行有两行,同样含单词Linux的行也有两行,而作为起始行与结束行的都时匹配到的第一个结果,即遵循懒汉模式

  • s 替换行

    #将第一行中"the whole word"替换为"a student"randolf@localhost:~/test $ sed 's/the whole word/a student/' sed.txt 0.I am a student1.hello word2.you are so cute3.what do you think of the party4.I am so glad to tell you that I am crazy about Linux!5.Linux is better than Windows much more.#这里替换的只是sed模式空间中的内容,若想要直接操作员文本,可以使用选项-irandolf@localhost:~/test $ sed -i 's/the whole word/a student/' sed.txt#当我们直接操作原文本时,同样也是不打印模式空间的randolf@localhost:~/test $ cat sed.txt 0.I am a student1.hello word2.you are so cute3.what do you think of the party4.I am so glad to tell you that I am crazy about Linux!5.Linux is better than Windows much more.

    sed的内置命令s中的边界符除了“/”,还可以使用“#”、”@”等特殊符号,常用于避免和原文本中的符号产生冲突,尽管也可以使用转义符避免冲突,不过转义符可能让你眼花缭乱。。

    举个例子

    #使用vim将刚刚的文本第一行修改为"0.Oh/my/god,dear me!",并执行复制cp sed.txt sed2.txt#目标:将Oh/my/god修改为honey#1.使用"@"作为定界符修改sed.txtrandolf@localhost:~/test $ sed 's@Oh/my/god@honey@' sed.txt |head -n 10.honey,dear me!#2.使用"/"作为定界符修改sed2.txtrandolf@localhost:~/test $ sed 's/Oh\/my\/god/honey/' sed2.txt |head -n 10.honey,dear me!#尽管都能实现操作,可这视觉效果实在不堪,让我这老花眼晕一会。。。
  • d 删除行

    #读入模式空间后直接删除读入的行,不让他打印到屏幕上来#删除1到3行randolf@localhost:~/test $ sed '1,3d' sed.txt 3.what do you think of the party4.I am so glad to tell you that I am crazy about Linux!5.Linux is better than Windows much more.#操作原文本,删除第一行#先瞄一眼,未删除之前第一二行是啥randolf@localhost:~/test $ sed -n '1p' sed.txt| head -n 20.Oh/my/god,dear me!1.hello word#执行删除命令randolf@localhost:~/test $ sed -i '1d' sed.txt randolf@localhost:~/test $ sed -n '1p' sed.txt| head -n 11.hello word#看到了吧,原文件中第1行成功删除,本来的第2行上位成第一行
  • a 目标行后面追加一行

    #最后一行后面增加一行内容,"The earth is beautiful"randolf@localhost:~/test $ sed -i '$a The earth is beautiful' sed.txt randolf@localhost:~/test $ sed -n '$p' sed.txt The earth is beautiful#成功!!!
  • i 目标行前面追加一行

#第一行前面增加一行内容,"This is a start line added just now!"randolf@localhost:~/test $ sed -i '1i This is a start line added just now!' sed.txt randolf@localhost:~/test $ sed -n '1p' sed.txt This is a start line added just now!#So easy!!!

三剑客之Awk

awk作为三剑客中最最复杂的老大哥,常常被称为awk语言,那么,详细解释是不可能的,这辈子都不可能的。。。聊点皮毛

1.awk初见面

1.1awk的简单详情

1977年由Alfred Aho 、Peter Weinberger 和 Brian Kernighan这三位同学创造,并以其名字的首字母命名该语言。

版本:awk同样分为不同的版本,如gawk、dawk、pawk,mawk等,在Linux里常使用的是gawk(红帽系列)、和mawk(乌班图系列)。我在使用的是rhel的社区版centos7,所以记录的也将是gawk的使用。

1.2 awk的工作机制

相似其余两位剑客(sed、grep),awk也是按行读取,过滤客户给定的匹配模式,并且执行特定的解决动作

组成部分(重要):pattern {action}

即匹配的模式(支持正则)和对匹配到的内容所执行的解决动作

两个特殊的模式:BEGIN END顾名思义,这两家伙分别表示在读取模式所匹配的数据之前执行,和在一律读取完数据之后执行

两个注意点:1.若未给定模式,则匹配所有 2.若没有指明解决行为,则默认执行打印动作print

毫不夸张地说,了解awk的组成,也就掌握其一半的使用能力了。

2.常用选项

Usage: awk [POSIX or GNU style options] -f progfile [--] file ...Usage: awk [POSIX or GNU style options] [--] 'program' file ...POSIX options:      GNU long options: (standard)    -f progfile     --file=progfile #从脚本中加载awk的命令    -F fs           --field-separator=fs #指定分隔符    -v var=val      --assign=var=val   #解决动作执行前设置一个变量val

-f加载的脚本中放置的是awk结构的命令,包括 pattern {action}

当需要指定多个分隔符时,可以以通过内置变量FS设置

多个动作解决条件以空格隔开,如{action1} {action2} {action3}…..

#案例素材randolf@zrm:~/test $ cat test centos|ubuntu|archapple,orange,banana dog cat#以|为分隔符,打印$3、$NFrandolf@zrm:~/test $ awk -F '|' '{print $NF}' testarchapple,orange,banana dog catrandolf@zrm:~/test $ awk -F '|' '{print $3}' testarchNF为内置变量,表示当前记录的个数,那么思考一下,$3的打印结果为什么第二行为空呢?我们前面提到awk是按行读取的,所以对于awk来说每一行就是一个操作范围,第一行被"|"分为三个字段,因而记录个数为3,即$NF的值是3,所以第一行的值输出相同;而第二行没有分隔符"|",所以整行只有一个字段记录,因而$NF的值为1,输出整行,而$3在第二行不存在,所以输出空白行。#重新编辑test文本内容randolf@zrm:~/test $ cat testcentos|ubuntu|archapple,orange,banana dog catnihaoa,xiongdiwoshiyizhishuaiguo#编写简单脚本供awk调用randolf@zrm:~/test $ echo "/^$/ {print \"我是一只空行\"}" > haha   #双引号需要转义randolf@zrm:~/test $ cat haha /^$/ {print "我是一只空行"}    #注意中间有空格randolf@zrm:~/test $ awk -f awk.sh test我是一只空行我是一只空行#BEGIN字段应用举例(2014年兄弟连 沈超李明老师经典教程)randolf@zrm:~/test $ awk  '{FS=":"} {print $1}' /etc/passwd |head -4root:x:0:0:root:/root:/bin/bashbindaemonadmrandolf@zrm:~/test $ awk  'BEGIN{FS=":"} {print $1}' /etc/passwd |head -4rootbindaemonadm#内容太长仅以4行为例,看到了么,未加BEGIN时第一行没有被分隔,哈哈,是不是蒙圈了?其实很好了解,awk会事前读取一行文本的内容,而后才会去找前面的条件,此处为设定的分隔符,嗯哼?想一想前面提到过的BEGIN的定义,BEGIN做两大特殊模式之一,表示在读取模式所匹配的数据之前执行,所以呢,加上BEGIN后,awk会先读取BEGIN后的条件。^_^

3.内置变量

变量名称形容
ARGC命令行参数个数
FILENAME当前输入文档的名称
FNR当前输入文档的记录编号,多个输入文档时有用
NR输入流当前记录编号
NF当前记录的字段个数
FS字段分隔符
OFS输出字段分隔符,默认是空格
ORS输出记录分隔符,默认换行符 \n
RS输入记录分隔符,默认换行符

4.表达式与操作符

4.1表达式的组成部分

表达式由变量,常量,函数,正则表达式,操作符组成
awk中变量有字符变量和数字变量,假如在awk中定义变量没有初始化,则初始化值为空字符或者0。字符操作必需加引号,如 a=”hello word”

4.2 常见操作符

+ – * / (加减乘除。。)

% 取余 ^ 幂运算 ++ — += -= *+ /= ‘>’

<       >=      <=       == 等于   !=     ~匹配     !~不匹配   &&与      ||或者
#操作符简单举例randolf@zrm:~/test $ echo test  | awk 'x=2 {print x+=1}'3randolf@zrm:~/test $ echo hello | awk 'x=1,y=3 {print x*2,y*3}'2 9#表达式与模式END结合使用randolf@zrm:~/test $ awk '/^$/ {x+=1} END {print x}' test2#打印root客户的UID,cat一下知道,/etc/passwd文件中第三个字段是客户的UIDrandolf@zrm:~/test $ awk -F: '$1~/root/ {print $3}' /etc/passwd0
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 三剑客基础详解

发表回复