1.通配符和正则表达式

通配符

  • 说白了一般只用于文件名匹配,它是由shell解析的,比如 find,ls,cp,mv等

shell常见通配符

  1. *:匹配0或多个字符
  2. ?:匹配任意一个字符
  3. [list]:匹配list中任意单个字符
  4. [c1c2]:匹配c1c2中任意单个字符
  5. [^c1c2]/[!c1c2]:不匹配c1c2中任意字符
  6. {string1,string2,...}:匹配{}中任意单个字符串

shell元字符

  1. IFS:<tab>/<space>/<enter>
  2. CR:<enter>
  3. =:设定变量
  4. $:取变量值
  5. >、< :重定向
  6. |:管道
  7. &:后台执行命令
  8. ():在子shell中执行命令/运算或命令替换
  9. {}:函数中执行/变量替换的界定范围
  10. ;:命令结束后,忽略其返回值,继续执行下一个命令
  11. &&:命令结束后,若为true,继续执行下一个命令
  12. ||:命令结束后,若为false,继续执行下一个命令
  13. !:非
  14. #:注释
  15. \:转义符

shell转义符

' ':硬转义,内部所有shell元字符,通配符都会被关掉
" ":软转移,内部

正则表达式

  • 正则表达式是用来匹配字符串的,针对文件内容的文本过滤工具里,大都用到正则表达式,如vi,grep,awk, sed等

  • 字符匹配

##字符匹配
.:匹配任意单个字符
[]:匹配指定范围内任意单个字符
[^]:匹配指定范围外任意单个字符
[:alnum:]:字母与数字
[:ascii:]:ASCII字符
[:blank:]:空格或制表符
[:cntrl:]:ASCII控制字符
[:digit:]:数字
[:graph:]:非控制、非空格字符
[:lower:]:小写字母
[:print:]:可打印字符
[:punct:]:标点符号字符
[:space:]:空白字符,包括垂直制表符
[:upper:]:大写字母
[:xdigit:]:十六进制数字
  • 匹配次数
##匹配次数
*:匹配前面的字符任意次数
.*:匹配任意长度的字符
\?:匹配其前面字符0或1次,即前面的可有可无
\+:匹配其前面的字符至少1次
\{m\}:匹配前面的字符m次
\{m,n\}:匹配前面的字符至少m次,至多n次
\{0,n\}:匹配前面的字符至多n次
\{m,\}:匹配前面的字符至少m次
  • 位置锚定
##位置锚定
^:行首锚定,用于模式的最左侧
$:行末锚定,用于模式的最右侧
^PATTERN$:用于模式匹配整行;
^$:空行
\< 或 \b:词首锚定,用于单词模式的左侧
\> 或 \b:词尾锚定,用于单词模式的右侧
\<PATTERN\>:匹配整个单词
  • 分组
##分组
\(\):将一个或多个字符捆绑在一起;当作一个字符
\(xy\)*ab

Note:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命令方式为:
\1,\2,\3……
\1:从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;
\(ab\+\(xy\)*\):
\1:ab\+\(xy\)*
\2:xy
  • 拓展正则表达式
##字符匹配
.
[]
[^]

##次数匹配
*
?:0次或1次
+:1次或多次
{m}:匹配m次
{m,n}:至少m次,至多n次

##位置锚定
##分组
()

##或者
a|b
C | cat :C或cat
(C|c)at : C或c

2.计划任务

  • 计划任务主要是做一些周期性的任务,目前主要用途是定期备份数据

一次性调度

  • 语法格式
at <TIMESPEC>
    now +5min
    teatime tomorrow (teatime is 16:00)
    noon +4 days
    5pm august 3 2021
  • 安装at并开启
[root@localhost ~]# yum install -y at
[root@localhost ~]# systemctl restart atd
[root@localhost ~]# systemctl enable  atd
#一分钟后执行任务
[root@localhost ~]# at now +1min
at> useradd zhangsan<EOT>
job 1 at Tue Jan 26 10:45:00 2021
[root@localhost ~]# atq
1    Tue Jan 26 10:45:00 2021 a root
  • 非交互模式:写进文本里再交给at
[root@localhost ~]# vim user_add.jobs 
touch /root/'date +%F'.txt
useradd zhangsan

[root@localhost ~]# at now+1min < user_add.jobs 
job 2 at Tue Jan 26 10:49:00 2021

用户级循环调度 crond

crond进程每分钟会处理一下计划任务

  • crond在使用前必须要启动守护进程
[root@localhost ~]# systemctl start crond
[root@localhost ~]# systemctl enable crond

##存储位置
/var/spool/cron
  • 相关命令
[root@localhost ~]# crontab -l # 列出当前用户所有计划任务
[root@localhost ~]# crontab -r # 删除当前用户计划任务
[root@localhost ~]# crontab -e # 编辑当前用户计划任务


#管理员可以使用 -u username,去管理其他用户的计划任务
[root@localhost ~]# crontab -e -u zhangsan

# 这个文件中加入的用户名无法使用cron
[root@localhost ~]# vi /etc/cron.deny
  • 格式
##如果是脚本的话脚本必须得有x权限
# 分 时 日 月 周 命令
* 表示任何数字都符合
0 2 * * * /run.sh     # 每天的2点
0 2 14 * * /run.sh    # 每月14号2点
0 2 14 2 * /run.sh    # 每年2月14号2点
0 2 * * 5 /run.sh     # 每个星期5的2点
0 2 * 6 5 /run.sh     # 每年6月份的星期5的2点
0 2 2 * 5 /run.sh     # 每月2号或者星期5的2点 星期和日同时存在,就是或的关系
0 2 2 6 5 /run.sh     # 每年6月2号或者星期5的2点
*/5 * * * * /run.sh   # 每隔5分钟执行一次
0 2 1,4,6 * * /run.sh # 每月1号,4号,6号的2点
0 2 5-9 * * /run.sh   # 每月5-9号的2点
* * * * * /run.sh     # 每分钟
0 * * * * /run.sh     # 每整点
* * 2 * * /run.sh     # 每月2号的每分钟

系统级循环调度

  • 作用:

    • 临时文件的清理 /tmp /var/tmp
    • 系统信息的采集 sar
    • 日志的轮转(切割) lgrotate
    • 通常不是由用户定义
  • 文件位置:/etc/crontab
[root@localhost ~]# vim /etc/crontab # 默认没有定义任何计划任务
[root@localhost ~]# ls /etc/cron.d # 定义的计划任务每个小时会执行
0hourly sysstat
[root@localhost ~]# cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly 
# 每小时01分以root身份执行/etc/cron.hourly/目录下的所有脚本
  • crond 仅仅会执行每小时定义的脚本 /etc/cron.hourly
[root@localhost ~]# ls /etc/cron.hourly/
[root@localhost ~]# cat /etc/cron.hourly/0anacron

/usr/sbin/anacron -s # anacron是用来检查是否有错过的计划任务需要被执行

[root@localhost ~]# vi /etc/anacrontab
1 5 cron.daily nice run-parts /etc/cron.daily
#每天开机 5 分钟后就检查 /etc/cron.daily 目录内的文件是否被执行,如果今天没有被执行,那就执行

7 25 cron.weekly nice run-parts /etc/cron.weekly
#每隔 7 天开机后 25 分钟检查 /etc/cron.weekly 目录内的文件是否被执行,如果一周内没有被执行,就会执行
monthly 45 cron.monthly nice run-parts /etc/cron.monthly
#每隔一个月开机后 45 分钟检查 /etc/cron.monthly 目录内的文件是否被执行,如果一个月内没有被执行,那就执行

3.三剑客之grep

  • 过滤文本内容 | 选项 | 描述 | | —- | —- | | -E :—extended—regexp | 模式是扩展正则表达式(ERE) | | -i :—ignore—case | 忽略大小写 | | -n: —line—number | 打印行号 | | -o:—only—matching | 只打印匹配的内容 | | -c:—count | 只打印每个文件匹配的行数 | | -B:—before—context=NUM | 打印匹配的前几行 | | -A:—after—context=NUM | 打印匹配的后几行 | | -C:—context=NUM | 打印匹配的前后几行 | | —color[=WHEN] | 匹配的字体颜色,别名已定义了 | | -v:—invert—match | 打印不匹配的行 | | -e | 多点操作eg:grep -e “^s” -e “s$” |

例子

[root@localhost ~]# cat test.txt
asdkahsduoa
aslkdsl
oiofr
sdjo
A
F
aSDD
CASDC
asdo
ca
#打印出所有的a无论大小写 : -i选项
[root@localhost ~]# grep -i 'a' test.txt 

#打印出所有的a无论大小写,并且显示该字符串所在的行 : -n选项
[root@localhost ~]# grep -in "a" test.txt

#仅仅打印出所有匹配的字符串: -o选项
[root@localhost ~]# grep -o 'a' test.txt 
a
a
a
a
a
a
a

#打印出匹配的字符串有多少行 -c选项
[root@localhost ~]# grep  -c 'a' test.txt 
5

#:打印出字符S前面的2行 -B
[root@localhost ~]# grep -B 2 's' test.txt 
asdkahsduoa
aslkdsl
oiofr
sdjo
--
aSDD
CASDC
asdo

#打印出字符S后面的2行 -A
[root@localhost ~]# grep -A 2 's' test.txt 
asdkahsduoa
aslkdsl
oiofr
sdjo
A
F
--
asdo
ca

#打印出字符S前后2行 -C
[root@localhost ~]# grep -C 2 's' test.txt

#打印出不包含大小s的所有行 取反 -v
[root@localhost ~]# grep -iv 's' test.txt
  • grep可以从文件当中直接搜索某个关键词,也可以从标准输入里面搜索
[root@localhost ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

[root@localhost ~]# cat /etc/passwd | grep "root"
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

正则表达式(基于grep)

  • 功能就是用来检索、替换那些符合某个模式(规则)的文本,正则表达式在每种语言中都会有;
  • 正则表达式就是为了处理大量的文本或字符串而定义的一套规则和方法
  • 通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤,替换或输出需要的字符串
  • Linux正则表达式一般以行为单位处理

常用

  • 删除注释和空行
[root@localhost ~]# grep -Ev '^$|^#' 1.txt 
[root@localhost ~]# grep -v -e '^$' -e '^#' 1.txt

4.三剑客之sed

  • Linux sed命令是利用script来处理文本文件。
  • sed可依照script的指令,来处理、编辑文本文件。
  • Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

参数说明

#以选项中指定的script来处理输入的文本文件。
-e<script> 或 --expression=<script>  #

#以选项中指定的script文件来处理输入的文本文件
-f<script文件> 或 --file=<script文件> 

-h 或 --help #显示帮助。
-n 或 --quiet 或 --silent #仅显示script处理后的结果。
-V 或 --version #显示版本信息。

动作说明

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c :取代行, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d :删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
s :取代,可以直接进行取代的工作哩!通常这个s的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!

以行为单位的增/删

将 /etc/passwd 的内容列出并且列印行号,同时,请将第 2~5 行删除
[root@localhost ~]# nl /etc/passwd | sed '2,5d'

#sed 的动作为 '2,5d' ,那个 d 就是删除!因为2-5行给他删除了,所以显示的数据就没有2-5 行罗~ 另外,注意一下,原本应该是要下达 sed -e 才对,没有-e也行啦!同时也要注意的是, sed 后面接的动作,请务必以 '' 两个单引号括住喔!

将 /etc/passwd 的内容列出并且列印行号,只删除第二行
[root@localhost ~]# nl /etc/passwd | sed '2d'

要删除第 3 到最后一行
[root@localhost ~]# nl /etc/passwd | sed '3,$d'

在第二行后(亦即是加在第三行)加上『hello world』字样
[root@localhost ~]# nl /etc/passwd | sed -e '2a\hello world'

加在第二行前面
[root@localhost ~]# nl /etc/passwd | sed -e '1a hello world'
[root@localhost ~]# nl /etc/passwd | sed '2i\ello world'

增加多行文字
[root@localhost ~]# nl /etc/passwd | sed -e '2a\hello world \nnihao'

以行为单位的替换与显示

将第2-5行的内容取代成为『No 2-5 number』
[root@localhost ~]# nl /etc/passwd | sed  '2,5c no 2-5 number'

仅列出 /etc/passwd 文件内的第 5-7 行
[root@localhost ~]# nl /etc/passwd | sed -n  '5,7p '

数据的搜寻

#显示
搜索 /etc/passwd有root关键字的行
[root@localhost ~]# nl /etc/passwd | sed -n  '/root/p '

#删除
删除/etc/passwd所有包含root的行,其他行输出
[root@localhost ~]# nl /etc/passwd | sed '/root/d'

#执行命令
搜索/etc/passwd,找到root对应的行,执行后面花括号中的一组命令,每个命令之间用分号分隔,这里把bash替换为blueshell,再输出这行
[root@localhost ~]# nl /etc/passwd | sed -n '/root/{s/bash/helloooo/;p;q}'
最后的q是退出,不然会继续找下去

#替换
除了整行的处理模式之外, sed 还可以用行为单位进行部分数据的搜寻并取代
sed 's/要被取代的字串/新的字串/g'
[root@localhost ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.91.128 netmask 255.255.255.0 broadcast 192.168.91.255
inet6 fe80::2de4:b37a:36e9:ae2e prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:d3:76:83 txqueuelen 1000 (Ethernet)
RX packets 33461 bytes 32133707 (30.6 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 11322 bytes 1300148 (1.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 10 bytes 697 (697.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 10 bytes 697 (697.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

##取有IP地址那一行
[root@localhost ~]# ifconfig | sed -n '/netmask/p'
inet 192.168.91.128 netmask 255.255.255.0 broadcast 192.168.91.255
inet 127.0.0.1 netmask 255.0.0.0

##删除IP地址前面和后面的东西
 ifconfig | sed -n '/netmask/p' | sed 's/ ^.*inet/ /g' | sed '/*.brocast/d'