Shell—grep、sed、awk

Shell学习

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。

Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。

Shell是 Linux系统中自带的语言

【扩展】:

机器语言

汇编语言

高级语言

  • 编译型 ===> 翻译 ===> 计算机 (跨平台性能差,执行速度快)
  • 解释型 ===> 解释器 ===> 翻译 ===> 计算机 (跨平台性能强,执行速度慢)

1. Shell如何执行用户的指令

Shell有两种执行指令的方式

  • 用户事先编写一个sh脚本文件,内含Shell脚本,然后使用Shell程序执行该脚本,这种方式习惯称为Shell编程
  • 用户直接在Shell界面上执行Shell命令,由于Shell界面的关系,大家习惯一行行的书写,很少写成成套的程序来执行,所以也称命令行

2. Shell的分类

Linux中默认的Shell是 /bin/bash ,流行的Shell有ash、bash、ksh、csh、zsh等,不同的Shell都有自己的特点以及用途

3. grep命令

3.1 grep 命令格式

功能:grep命令是Linux系统中最重要的命令之一,功能是从文本文件管道数据流中筛选匹配的数据,如果再配合正则表达式,功能十分强大,是Linux运维人员必备的命令

grep [选项] pattern  filename...
命令  参数  匹配模式   文件数据
  • 在每个file 或是标准输入中查找 pattern ,默认pattern是一个基本正则表达式
  • 用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设grep指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为“-”,则grep指令会从标准输入设备读取数据。
3.2 grep 命令选项

grep常用参数:

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN]...  [-f FILE]...  [FILE...]

OPTIONS:
-a 不要忽略二进制数据。
-A<显示列数> 除了显示符合范本样式的那一行之外,并显示该行之后的内容。
-b 在显示符合范本样式的那一行之外,并显示该行之前的内容。
-c 计算符合范本样式的列数。
-C<显示列数>或-<显示列数>  除了显示符合范本样式的那一列之外,并显示该列之前后的内容。
-d<进行动作> 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep命令将回报信息并停止动作。
-e<范本样式> 指定字符串作为查找文件内容的范本样式。
-E 将范本样式为延伸的普通表示法来使用,意味着使用能使用扩展正则表达式。
-f<范本文件> 指定范本文件,其内容有一个或多个范本样式,让grep查找符合范本条件的文件内容,格式为每一列的范本样式。
-F 将范本样式视为固定字符串的列表。
-G 将范本样式视为普通的表示法来使用。
-h 在显示符合范本样式的那一列之前,不标示该列所属的文件名称。
-H 在显示符合范本样式的那一列之前,标示该列的文件名称。
-i 忽略字符大小写的差别。
-l 列出文件内容符合指定的范本样式的文件名称。
-L 列出文件内容不符合指定的范本样式的文件名称。
-n 在显示符合范本样式的那一列之前,标示出该列的编号。
-q 不显示任何信息。
-R/-r 此参数的效果和指定“-d recurse”参数相同。
-s 不显示错误信息。
-v 反转查找。
-w 只显示全字符合的列。
-x 只显示全列符合的列。
-y 此参数效果跟“-i”相同。
-o 只输出文件中匹配到的部分。
--color: 匹配到的内容高亮显示
--include: 指定匹配的文件类型
--exclude: 过滤不需要匹配的文件类型
3.3 grep 实例

查找指定进程

不想显示grep本身进程,需在grep后加 -v 参数

[root@10-255-1-182 ~]# ps -ef|grep bash
root       387 18830  0 Sep15 ?        00:00:00 bash
root      2580 18830  0 Sep15 ?        00:00:00 bash
root      2707  4872  0 Jul30 ?        00:00:00 bash
root      2908 12870  0 Sep04 pts/0    00:00:00 bash
root     13493  4872  0 Sep22 ?        00:00:00 bash
root     15766 16382  0 12:01 pts/0    00:00:00 grep --color=auto bash  # grep本身进程
root     16382 16339  0 10:24 pts/0    00:00:00 -bash
root     21380 18830  0 Aug01 ?        00:00:00 bash
root     22622  4872  0 Aug18 ?        00:00:00 bash

输出test2.txt中含有从test.txt文件中读取出的关键字的内容行

[root@10-255-1-182 ~]# cat test.txt
周杰伦

[root@10-255-1-182 ~]# cat test2.txt
相见恨晚-彭佳慧.mp3
稻香-周杰伦.MP3
等你下课(with杨瑞代)-周杰伦.MP3
简单爱-周杰伦.MP3
繁华的寂静-文武贝.mp3
给我一首歌的时间-周杰伦.MP3
芊芊-回音哥.mp3
花沐然-不能说的密码(抖音版).mp3
蒲公英的约定-周杰伦.MP3

[root@10-255-1-182 ~]# cat test2.txt | grep -f test.txt
稻香-周杰伦.MP3
等你下课(with杨瑞代)-周杰伦.MP3
简单爱-周杰伦.MP3
给我一首歌的时间-周杰伦.MP3
蒲公英的约定-周杰伦.MP3

从文件中读取关键词进行搜索且显示行号

【注意】:n 必须在 f前面

[root@10-255-1-182 ~]# cat test2.txt | grep -nf test.txt
2:稻香-周杰伦.MP3
3:等你下课(with杨瑞代)-周杰伦.MP3
4:简单爱-周杰伦.MP3
6:给我一首歌的时间-周杰伦.MP3
9:蒲公英的约定-周杰伦.MP3

找出以’稻’开头的内容

[root@10-255-1-182 ~]# cat test2.txt | grep ^稻
稻香-周杰伦.MP3

输出非’稻’开头的内容

[root@10-255-1-182 ~]# cat test2.txt | grep ^[^稻]
相见恨晚-彭佳慧.mp3
等你下课(with杨瑞代)-周杰伦.MP3
简单爱-周杰伦.MP3
繁华的寂静-文武贝.mp3
给我一首歌的时间-周杰伦.MP3
芊芊-回音哥.mp3
花沐然-不能说的密码(抖音版).mp3
蒲公英的约定-周杰伦.MP3
过客-阿涵.mp3
过期的爱情-雨宗林.mp3
这片海-顾莉雅.mp3
避雨-任然.mp3
那么骄傲-周玥徐薇.mp3
青山黛玛-そばにいるね(留在我身边).mp3
顾莉雅-寂寞花火.mp3

4. sed命令

4.1 sed 介绍

sed (stream editor ) 流编辑器,常用来进行文本替换工作,与常用的交互式编辑器(vim)不同,sed 编辑器以批处理的方式来编辑文件,这比交互式编辑器快得多,可以快速的完成对数据的编辑修改。
sed是操作、过滤和转换文本内容的强大工具。常用功能包括对文件实现快速增删改查,其中查询的功能中最常用的两大功能是过滤(过滤指定字符串)、取行(取出指定行)。

sed编辑器会执行以下操作:

  • 一次从输入中读取一行数据
  • 根据所提供的编辑器命令匹配数据
  • 按照命令修改流中的数据
  • 将新的数据输出到STDOUT

sed 的工作原理

sed 命令是面向 进行处理的,每一次处理一行内容。处理时,sed 会把要处理的行存储在缓冲区中,接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。这个缓冲区被称为“模式空间”(pattern space)。

在这个处理过程中,sed 命令并不会对文件本身进行任何更改

例如: 利用sed删除test.txt中带b的内容,并没有改变原文件的内容,删除只是在模式空间执行的

[root@10-255-1-182 ~]# cat test3.txt
zhb
zhb
htt
htt
[root@10-255-1-182 ~]# sed '/b/d' test3.txt  # d 表示的删除
htt 
htt
[root@10-255-1-182 ~]# cat test3.txt
zhb
zhb
htt
htt
4.2 sed 命令格式
sed [options] edit_commands [file]

注意:sed 和 grep 不一样,不管是否找到指定的模式,它的退出状态都是0,只有当命令存在语法错误时,sed的退出状态才是非0

4.3 sed 支持正则表达式
^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。  
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\> 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。
4.4 sed 常用选项options
-n:不输出模式空间内容到屏幕,即不自动打印,只打印匹配到的行
-e:多点编辑,对每行处理时,可以有多个Script
-f:把Script写到文件当中,在执行sed时-f 指定文件路径,如果是多个Script,换行写
-r:支持扩展的正则表达式
-i:直接将处理的结果写入文件,即改变原文件
-i.bak:在将处理的结果写入文件之前备份一份
4.5 sed 编辑命令commands
d:删除模式空间匹配的行,并立即启用下一轮循环
p:打印当前模式空间内容,追加到默认输出之后
a:在指定行后面追加文本,支持使用\n实现多行追加
i:在行前面插入文本,支持使用\n实现多行追加
c:替换行为单行或多行文本,支持使用\n实现多行追加
w:保存模式匹配的行至指定文件
r:读取指定文件的文本至模式空间中匹配到的行后
=:为模式空间中的行打印行号
!:模式空间中匹配行取反处理
s///:查找替换,支持使用其它分隔符,如:s@@@,s###;
    加g表示行内全局替换;
    在替换时,可以加一下命令,实现大小写转换
    \l:把下个字符转换成小写。
    \L:把replacement字母转换成小写,直到\U或\E出现。
    \u:把下个字符转换成大写。
    \U:把replacement字母转换成大写,直到\L或\E出现。
    \E:停止以\L或\U开始的大小写转换
4.6 sed 高级编辑命令
h:把模式空间中的内容覆盖至保持空间中
H:把模式空间中的内容追加至保持空间中
g:从保持空间取出数据覆盖至模式空间
G:从保持空间取出内容追加至模式空间
x:把模式空间中的内容与保持空间中的内容进行互换
n:读取匹配到的行的下一行覆盖 至模式空间
N:读取匹配到的行的下一行追加 至模式空间
d:删除模式空间中的行
D:删除 当前模式空间开端至\n 的内容(不再传 至标准输出),放弃之后的命令,但是对剩余模式空间重新执行sed
!: 表示后面的命令对所有没有被选定的行发生作用

在这里插入图片描述

读取第二行的下一行,然后输出模式空间的内容,此时模式空间中有两行

[root@10-255-1-182 ~]# cat test2.txt |sed -n '2{N;p}'
繁华的寂静-文武贝.mp4 给我一首歌的时间-周杰伦.MP3
芊芊-回音哥.mp4
4.7 sed 替换标志
g:在行内进行全局替换
w:将行写入文件
x:交换暂存缓冲区与模式空间的内容
y:将字符装换为另一字符
4.8 实例

sed 用s进行文本替换

[root@10-255-1-182 ~]# cat test2.txt
稻香-周杰伦.MP3 等你下课(with杨瑞代)-周杰伦.MP3 简单爱-周杰伦.MP3
繁华的寂静-文武贝.mp3 给我一首歌的时间-周杰伦.MP3
芊芊-回音哥.mp3
花沐然-不能说的密码(抖音版).mp3
蒲公英的约定-周杰伦.MP3 过客-阿涵.mp3 过期的爱情-雨宗林.mp3 这片海-顾莉雅.mp3
[root@10-255-1-182 ~]# sed 's/3/4/' test2.txt
稻香-周杰伦.MP4 等你下课(with杨瑞代)-周杰伦.MP3 简单爱-周杰伦.MP3
繁华的寂静-文武贝.mp4 给我一首歌的时间-周杰伦.MP3
芊芊-回音哥.mp4
花沐然-不能说的密码(抖音版).mp4
蒲公英的约定-周杰伦.MP4 过客-阿涵.mp3 过期的爱情-雨宗林.mp3 这片海-顾莉雅.mp3

默认情况下,替换命令只会替换掉目标文本在每行第一次出现的地方。

sed 's/3/4/g' test2.txt   # g 表示替换每行所有匹配到的内容

sed 's/3/4/5' test2.txt   # 5 表示替换每行第5个匹配到的内容

sed 's/3/4/g w test4.txt' test2.txt  # 将替换后的文件写入到test.txt 文件中

sed '2,4 s/3/4/g' test2.txt  # 替换2到4行,全行替换

sed 命令插入和附加文本

sed 编辑器使用i命令来向数据流中插入文本行,使用a命令来向数据流中附加文本行,

  • i 是在指定行前增加一个新行,
  • a是在指定行后增加一个新行
[root@10-255-1-182 ~]# sed 'i\hello world!' test2.txt  # 在每一行前面添加‘hello world’

[root@10-255-1-182 ~]# sed '1i\hello world!' test2.txt  # 在第一行前面添加‘hello world’

sed 命令修改行

使用命令c可以将数据流中的整行文本修改为新的行

sed '3 c\告白气球、告白气球' test2.txt   # 将第3行替换成'告白气球、告白气球'

5. awk 命令

5.1 awk 介绍

awk不仅是Linux系统一个命令,也是种编程语言,可以处理数据/文件生成Excel。

awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。

简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。

5.2 awk 语法格式
5.2.1 awk 命令行方式
awk [-F filed-separator] 'commands' input-file(s)
awk [选项参数] 'commands' var=value file(s)
  • commands 是真正的AWK命令;[-F 域分隔符]是可选的;input-file(s)是待处理文件
  • awk中,文件的每一行中,由域分隔符分开的每一项称为一个域。通常在不指定-F 域分隔符的情况下,默认域分隔符是空格
5.2.2 awk 命令插入一个单独文件调用
awk -f awk-script-file input-file(s)
awk [选项参数] -f scriptfile var=value file(s)
  • -f 选项加载 awk-script-file 中的awk脚本,input-file(s)是待处理的文件
5.2.3 shell脚本方式
  • 将所有的awk命令插入一个文件,并使 awk 程序可执行,然后awk命令解释器作为脚本的首行,一遍通过键入脚本名称来调用,相当于shell脚本首行的:#!/bin/sh 可以换成:#!/bin/awk
5.3 awk工作原理

awk工作流程可分为三个部分:

  • 读输入文件之前执行的代码段(由BEGIN关键字标识)
  • 主循环执行输入文件代码段
  • 读输入文件之后的代码段(由END关键字标识)
5.3.1 awk命令结构
awk 'BEGIN{ commands } parrent{ commands } END{ commands }'

开始块(BEGIN)

BEGIN {awk-commands}
  • 开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次

  • BEGIN是awk的关键字,必须大写

  • 开始部分是可选的

主体块(BODY)

/pattern/{awk-commands}

结束块(END)

END {awk-commands}

END也是awk的关键字,必须大写,也是可选的

5.4 awk 选项参数说明
  • -F fs or --field-separator fs

    指定输入文件分隔符,fs是一个字符串或者是一个正则表达式

  • -v var=value or --asign var=value

    复制一个用户定义变量

  • -f scriptfile or --file scriptfile

    从脚本文件中读取awk命令

5.5 awk 基本用法
5.5.1 行匹配语句(默认分隔符)
awk '{[pattern] action}' {filenames}  # 行匹配语句 awk '' 只能用单引号

例:每行按空格分割,输出文件中的1、4项

默认情况下,awk 会将如下变量分配给它在文本行中发现的数据字段:

  • $0 代表整个文本行;
  • $1 代表文本行中的第 1 个数据字段;
  • $2 代表文本行中的第 2 个数据字段;
  • $n 代表文本行中的第 n 个数据字段。
[root@10-255-1-182 ~]# cat log.txt
this is a test
Are you like awk
告白 气球  周 杰伦
手写 的从前  周 杰伦
[root@10-255-1-182 ~]# awk '{print $1,$4}' log.txt
this test
Are awk
告白 杰伦
手写 杰伦
5.5.2 指定分隔符
awk -F  #-F相当于内置变量FS, 指定分割字符

例:

# 使用","分割
[root@10-255-1-182 ~]# awk -F, '{print $1,$2}'   log.txt  
this is a test
Are you like awk
告白 气球  周 杰伦
手写 的从前  周 杰伦
# 或者使用内建变量
[root@10-255-1-182 ~]# awk 'BEGIN{FS=","} {print $1,$2}'   log.txt
this is a test
Are you like awk
告白 气球  周 杰伦
手写 的从前  周 杰伦
# 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
[root@10-255-1-182 ~]# awk -F '[ ,]'  '{print $1,$2,$3}'   log.txt
this is a
Are you like
告白 气球
手写 的从前
5.5.3 设置变量
awk -v  # 设置变量

例:

[root@10-255-1-182 ~]# awk -va=1 '{print $1,$1+a}' log.txt
this 1
Are 1
告白 1
手写 1
[root@10-255-1-182 ~]# awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
this 1 thiss
Are 1 Ares
告白 1 告白s
手写 1 手写s
5.5.4 调用脚本
awk -f {awk脚本} {文件名}

例:

[root@10-255-1-182 ~]# cat score.txt
张三    1001 80 99 100
李四    1002 92 78 95
王五    1003 78 98 77
狗蛋    1004 98 89 56
[root@10-255-1-182 ~]# cat aaa.awk
#!/bin/awk -f
# 运行前
BEGIN {
        math = 0
        english = 0
        computer = 0

        printf "姓名    学号 数学 英语 计算机 总分\n"
        printf "*******************************\n"
}

# 运行中
{
        math+=$3
        english+=$4
        computer+=$5
        printf "%-6s %-4s %-4d %4d %4d %4d\n", $1, $2, $3, $4, $5, $3+$4+$5
}

# 运行后
END {
        printf "*******************************\n"
        printf "TOTAL:%10d %8d %8d \n", math, english, computer
        printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
[root@10-255-1-182 ~]# awk -f aaa.awk score.txt
姓名    学号 数学 英语 计算机 总分
*******************************
张三     1001 80     99  100  279
李四     1002 92     78   95  265
王五     1003 78     98   77  253
狗蛋     1004 98     89   56  243
*******************************
TOTAL:       348      364      328
AVERAGE:     87.00    91.00    82.00

运算符

运算符描述
= += -= *= /= %= ^= **=赋值
?:C条件表达式
||逻辑或
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ –增加或减少,作为前缀或后缀
$字段引用
in数组成员
5.5.5 忽略大小写
[root@10-255-1-182 ~]# cat log.txt
this is a test
Are you like awk
This is a test
告白 气球  周 杰伦
手写 的从前  周 杰伦
[root@10-255-1-182 ~]# awk 'BEGIN{IGNORECASE=1} /this/' log.txt
this is a test
This is a test
[root@10-255-1-182 ~]#
5.6 awk内置变量
变量描述
$n当前记录的第n个字段,字段间由FS分隔
$0完整的输入记录
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR各文件分别计数的行号
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF一条记录的字段的数目
NR已经读出的记录数,就是行号,从1开始
OFMT数字的输出格式(默认值是%.6g)
OFS输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP数组下标分隔符(默认值是/034)

例:

# 输出顺序号 NR, 匹配文本行号.
[root@10-255-1-182 ~]# awk '{print NR,FNR,$1,$2,$3}' log.txt
1 1 this is a
2 2 Are you like
3 3 This is a
4 4 告白 气球 周
5 5 手写 的从前 周
# 指定输出分隔符
[root@10-255-1-182 ~]# awk '{print $1,$2,$5}' OFS=" $ "  log.txt
this $ is $
Are $ you $
This $ is $
告白 $ 气球 $
手写 $ 的从前 $
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值