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 = 0english = 0computer = 0printf "姓名 学号 数学 英语 计算机 总分\n"printf "*******************************\n"
}# 运行中
{math+=$3english+=$4computer+=$5printf "%-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, computerprintf "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 $
告白 $ 气球 $
手写 $ 的从前 $