目录
3.1.2 示例:查找修改时间在7天之前或文件名以.bak结尾的文件
一.Shell编程之正则表达式
1、正则表达式
1.正则表达式概述
正则表达式通常用于判断语句中,用来检查某一字符串是否满足某一格式。
正则表达式是由普通字符与元字符组成。普通字符包括小写字母、数字、标点符号及一些其他符号。元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
2.正则表达式的分类
正则表达式根据从POSIX BRE或者POSIX ERE标准可以分为基本正则表达式和扩展正则表达式。
基本正则表达式
支持的工具:grep
、egrep
、sed
、 awk
,注意grep
要配合-E
或者-P
使用。
元字符 | 含义及用法 |
---|---|
\ | 转义字符,用于取消特殊符号的含义,例: \! 、 \n 、 \$ 等 |
^ | 匹配字符串开始的位置,例:^a 、^the 、^# 、^[a-z] |
$ | 匹配字符串结束的位置,例: word$ 、^$ 匹配空行 |
. | 匹配除\n 之外的任意的一个字符,例: go.d 、g..d 。如果想要匹配包含\n字符可以使用 [.\n] |
* | 匹配前面子表达式0次或者多次,例: goo*d 、 go.*d |
[list] | 匹配list列表中的一个字符,例: go[ola]d ,[abc] 、[a-z] 、[a-z0-9] 、[0-9] 匹配任意一位数字 |
[^list] | 匹配任意非list列表中的一个字符,例:[^0-9] 、[^A-Z0-9] 、[^a-z] 匹配任意一位非小写字母 |
\{n\} | 匹配前面的子表达式n次,例: go\{2\}d 、 [0-9]\{2\} 匹配两位数字 |
\{n,\} | 匹配前面的子表达式不少于n次,例: gol{2,l}d 、[0-9]\{2,\} 匹配两位及两位以上数字 |
\{n,m\} | 匹配前面的子表达式n到m次,例 : go\{2,3\}d 、[0-9]\{2,3\} 匹配两位到三位数字 |
注: egrep 、 awk 使用{n} 、{n,} 、{n,m} 匹配时 {} 前不用加 \ | |
\w | 匹配包括下划线的任何单词字符。 |
\W | 匹配任何非单词字符。等价于[^A-Za-z0-9_] 。 |
\d | 匹配一个数字字符。 |
\D | 匹配一个非数字字符。等价于[^0-9] 。 |
\s | 空白符。 |
\S | 非空白符。 |
扩展正则表达式**
支持的工具:egrep
、awk
,注意:使用grep
要配合-E
或者-P
使用,sed
要配合-r
使用。
元字符 | 含义及用法 |
---|---|
+ | 匹配前面子表达式1次以上,例: go+d ,将匹配至少一个o ,如god 、good 、goood 等 |
? | 匹配前面子表达式0次或者1次,例: go?d ,将匹配gd 或god |
() | 将括号中的字符串作为一个整体,例1: g(oo)+d ,将匹配oo 整体1次以上,如good 、gooood 等 |
| | 以或的方式匹配字符串,例:g(oo|la)d ,将匹配good 或者 glad |
3.使用案例
首先创建一个小文件
[root@localhost ~]# cat test1.txt
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# cat test1.txt | grep -E "g+d"
gd
先是* ^ $的用法
root@localhost ~]# cat test1.txt | grep "^g"
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
gold
goad
[root@localhost ~]# cat test1.txt | grep "d$"
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
oooogooood
ooooogd
gold
goad
[root@localhost ~]# cat test1.txt | grep "g*d"
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
oooogooood
ooooogd
gold
goad
[] [^]的用法
[root@localhost ~]# cat test1.txt | grep "[a-z]"
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# cat test1.txt | grep "[^a-z]"
abccba123
[root@localhost ~]# echo abc >> test1.txt
[root@localhost ~]# cat test1.txt | grep "[^a-z]"
abccba123
\{n\}
等命令的用法
[root@localhost ~]# cat test1.txt | egrep "o{3}"
goood
gooood
goooabcd
gooooood
gooooooodddd
oooogooood
ooooogd
\d,\W的用法
[root@localhost ~]# echo ";;;;...??????*&&^&" >> test1.txt
[root@localhost ~]# cat test1.txt | egrep "\W"
;;;;...??????*&&^&
[root@localhost ~]# cat test1.txt | egrep "\d"
gd
god
good
goood
gooood
goooabcd
gooooood
gooooooodddd
oooogooood
ooooogd
gold
goad
注意:egrep比grep -e 功能更全,但是有些功能并不支持
例题
电话例题
找出区号025开头的号码,且号码与区号间可以是空格、-、没有,号码必须是5或者8开头的八位数。
02588888888
025-5555555555
025 12345678
025 54321678
025ABC88888
025-85432109
028-85643210
0251-52765421
解
[root@localhost ~]# cat phone.txt | grep -E "^(025)[ -]?[58][0-9]{7}$"
02588888888
025 54321678
025-85432109
二、sed编辑器
1.sed编辑器概念
sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储一个命令文本文件中。
2.sed编辑器工作流程
sed 的工作流程主要包括读取、执行和显示三个过程:
读取:sed从输入流(文件、管道、标准输入〉中读取一行内容并存储到临时的缓冲区中(又称模式空间,pattern space)。 执行:默认情况下,所有的sed命令都在模式空间中顺序地执行,除非指定了行的地址,否则临时sed命令将会在所有的行上依次执行。
显示:发送修改后的内容到输出流。在发送数据后,模式空间将会被清空。
在所有的文件内容都被处理完成之前,上述过程将重复执行,直至所有内容被处理完。
注意:默认情况下所有的sed命令都是在模式空间内执行的,因此输入的文件并不会发生任何变化,除非是用重定向存储输出。
处理大文件较卡问题
流编辑器处理大文件比较卡可以使用两种方式来处理。sed命令将大文件分成若干个小文件读取。或者使用cat
命令读取全部文件放在临时缓冲区中,然后交给流编辑器(grep、sed、awk)进行处理,由于使用cat命令时IO消耗比较低。
3.sed编辑器用法
命令格式
sed -e '操作' 文件l 文件2 ...
sed -n -e '操作' 文件1 文件2 ...
sed -f 脚本文件 文件1 文件2 ...
sed -i -e '操作' 文件1 文件2 ...
sed -e 'n{ #n意为:指定行
操作l
操作2
...
}' 文件1 文件2 ...
常用选项
选项 | 含义 |
---|---|
-e 或--expression= | 表示用指定命令来处理输入的文本文件,只有一个操作命令时可省略,一般在执行多个操作命令使用。 |
-f 或--file= | 表示用指定的脚本文件来处理输入的文本文件。 |
-h 或--help | 显示帮助。 |
-n 、--quiet 或silent | 禁止sed编辑器输出,但可以与p 命令一起使用完成输出。 |
-i | 直接修改目标文本文件。 |
-r, --regexp-extended | 支持正则表达式 |
常用操作
操作 | 含义 |
---|---|
s | 替换,替换指定字符。 |
d | 删除,删除选定的行。 |
a | 增加,在当前行下面增加一行指定内容。 |
i | 插入,在选定行上面插入一行指定内容。 |
c | 替换,将选定行替换为指定内容。 |
y | 字符转换,转换前后的字符长度必须相同。 |
p | 打印,如果同时指定行,表示打印指定行;如果不指定行,则表示打印所有内容,如果有非打印字符,则以ASCII码输出。其通常与-n 选项一起使用。 |
= | 打印行号。 |
l (小写L) | 打印数据流中的文本和不可打印的AscII字符(比如结束符$ 、制表符\t ) |
常用方式:
打印内容
[root@localhost ~]# sed -n 'p' phone.txt
02588888888
025-5555555555
025 12345678
025 54321678
025ABC88888
025-85432109
028-85643210
0251-52765421
[root@localhost ~]# sed -n '/[ABC]/p' phone.txt
025ABC88888
寻址
[root@localhost ~]# cat /etc/passwd | sed -n '='
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[root@localhost ~]# sed -n '1p' passwd
sed:无法读取 passwd:没有那个文件或目录
[root@localhost ~]# sed -n '1p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# cat -n passwd | sed -n -e '1p'
cat: passwd: 没有那个文件或目录
[root@localhost ~]# cat -n /etc/passwd | sed -n -e '1p'
1 root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# cat -n /etc/passwd | sed -n -e '1,5p'
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost ~]# cat -n /etc/passwd | sed -n '/root/p'
1 root:x:0:0:root:/root:/bin/bash
10 operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# cat /etc/fstab | sed -n '/swap/p'
/dev/mapper/rl-swap none swap defaults 0 0
[root@localhost ~]# cat /etc/fstab | sed -n '/^\/dev/p'
/dev/mapper/rl-root / xfs defaults 0 0
/dev/mapper/rl-home /home xfs defaults 0 0
/dev/mapper/rl-swap none swap defaults 0 0
删除内容:(由于删除源文件会出问题,这里直接只列出命令,另外注意,删除时不要加 -n!!!!!)
[root@localhost ~]# sed 'd' testfile1 #全删
[root@localhost ~]# sed '3d' testfile1 #删除第3行
[root@localhost ~]# sed '2,4d' testfile1 #删除第2到4行
[root@localhost ~]# sed '$d' testfile1 #删除最后一行
[root@localhost ~]# sed '/^$/d' testfile1 #删除空行
[root@localhost ~]# sed '/nologin$/d' /etc/passwd #删除以nologin结尾的文件
[root@localhost ~]# sed '/nologin$/!d' /etc/passwd #"!"表示取反
[root@localhost ~]# sed '/2\|3/d' testfile2 #删除第2行和第3行
[root@localhost ~]# sed '/2/,/3/d' testfile2 #从第一个位置打开行删除功能,到第二个位置关闭行删除功能
[root@localhost ~]# sed '/1/,/3/d' testfile2 #从第一个包含1的行打开删除功能,到第一个包含3的行关闭删除功能,然后接着往下扫描重复之前操作,若包含3的行不存在,则一删到底。
替换内容
命令格式
行范围 s/旧字符/新字符串/替换标记
替换标记
数字 | 表明新字符串将替换第几处匹配的地方 |
g | 表明新字符串将会替换所有匹配的地方 |
p | 打印与替换命令匹配的行,与-n一起使用 |
w 文件 | 将替换的结果写到文件中 |
使用方式
将所有/某一个root换成ROOT进行替换
cat-n passwd | sed -n 's/root/ROOT/gp'
cat-n passwd | sed -n 's/root/ROOT/1p'
将前十行加上注释
cat -n passwd | sed -n 'l,10 s/n/#/p'
获取&前的内容批量打印
cat -n passwd | sed -内容‘s/*root.*/&&/p'
可以用sed来加入#成为注释来关闭掉一些功能
插入
cat -n passwd | swd '/root/c qweryuio'
读取第五行的 /etc/fstab文件
cat -n Passwd | sed -n '5r /etc/fstab'
将包含root的行剪到末尾,H表示复制到剪切板,G表示贴到指定行
sed '/root/{H:d};$G' passwd
高级使用(sed分组概念)
[root@localhost ~]# echo "111222333" | sed -r 's/(111)(222)/\2\1/'
222111333
[root@localhost ~]# echo "1112223333" | sed -r 's/(111)(222)/\2\1/'
2221113333
3.awk编辑器
1.概念
sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个"字段"然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print
的功能将字段数据打印显示。
在使用awk命令的过程中,可以使用逻辑操作符 &&
表示与、||
表示或、!
表示非;还可以进行简单的数学运算,如+
、-
、*
、/
、%
、^
分别表示加、减、乘、除、取余和乘方。
2.工作原理
逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。
3.用法
命令格式
awk 选项 '模式或条件 {操作}' 文件1 文件2 ...
awk -f 脚本文件 文件l 文件2 ...
常用选项
-F 指定分隔符
awk -F ',' '{print}' file1
常见的内建变量
内建变量 | 含义 |
---|---|
FS | 列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与-F 作用相同。 |
NF | 当前处理的行的字段个数。$NF 代表最后一个字段。 |
NR | 当前处理的行的行号(序数)。 |
$0 | 当前处理的行的整行内容。 |
$n | 当前处理行的第n个字段(第n列)。 |
FILENAME | 被处理的文件名。 |
RS | 行分隔符。awk从文件上读取资料时,将根据Rs的定义把资料切割成许多条记录,而awk比较倾向于将一行分成多个一次仅读入一条记录,以进行处理。预设值是\n 。 |
使用案例
显示文本的一行或1~10行
[root@localhost ~]# cat /etc/passwd | awk -F: 'NR==1{print}'
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# cat /etc/passwd | awk -F: 'NR>=1&&NR<=10{print}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
输出含有root的行
[root@localhost ~]# df -Th | awk '/root/{print $0}'
/dev/mapper/rl-root xfs 70G 8.0G 62G 12% /
[root@localhost ~]# df -Th | awk '/root/{print $5}'
62G
统计结尾
[root@localhost ~]# awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
3
此命令等同于grep -c "/bin/bash$" /etc/passwd
。
BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;awk再处理指定的文本,之后再执行END模式中指定的动作,END{}语句块中,往往会放入打印结果等语句。
按字段输出文本
输出每行中的第1、3个字段,以|分割
[root@localhost ~]# awk -F: '$3>100{print $1"|"$3}' /etc/passwd
nobody|65534
systemd-coredump|999
systemd-resolve|193
polkitd|998
geoclue|997
unbound|996
rtkit|172
pipewire|995
pulse|171
dnsmasq|988
qemu|107
clevis|987
usbmuxd|113
gluster|986
chrony|985
setroubleshoot|984
saslauth|983
libstoragemgmt|982
sssd|981
cockpit-ws|980
cockpit-wsinstance|979
flatpak|978
colord|977
gnome-initial-setup|976
pesign|975
shanshan|1000
usr1|1001
使用三元运算符输出内容
[root@localhost ~]# free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'
26%
输出每行内容和行号
[root@localhost ~]# vim file1.txt
aaa
aaa
bbb
ccc
aaa
bbb
aaa
~
[root@localhost ~]# awk '{a[$1]++}END{for(i in a){print a[i],i}}' file1.txt
4 aaa
1 ccc
2 bbb
[root@localhost ~]# awk '{a[$1]++}END{for(i in a){print a[i],i}}' file1.txt |sort -r
4 aaa
2 bbb
1 ccc
3.find命令详解
find命令是Unix和类Unix系统中一个强大的文件搜索工具,它允许用户在文件系统中按照不同的条件查找文件和目录。由于其灵活性和功能强大,find命令成为系统管理员和开发人员在维护文件系统和查找特定文件时的首选工具。本文将深入介绍find命令的基本语法、常用选项以及高级用法,以帮助读者更全面地了解和使用这个重要的Unix命令。
1、find基本语法
find命令的基本语法如下:
find [path...] [expression]
其中,path是查找的起始路径,可以是目录名、文件名或通配符。expression是用于指定搜索条件的表达式,它可以包含多个选项和操作符。
2、常用选项
选项 | 作用 |
---|---|
-amin<分钟> | 查找在指定时间曾被存取过的文件或目录,单位以分钟计算; |
- anewer<参考文件或目录> | 查找其存取时间较指定文件或目录的存取时间更接近现在的文件或目录; |
- atime<24小时数> | 查找在指定时间曾被存取过的文件或目录,单位以24小时计算; |
- cmin<分钟> | 查找在指定时间之时被更改过的文件或目录; |
- cnewer<参考文件或目录> | 查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录; |
- ctime<24小时数> | 查找在指定时间之时被更改的文件或目录,单位以24小时计算; |
- daystart | 从本日开始计算时间; |
- depth | 从指定目录下最深层的子目录开始查找; |
- expty | 寻找文件大小为0 Byte的文件,或目录下没有任何子目录或文件的空目录; |
- exec<执行指令> | 假设find指令的回传值为True,就执行该指令; |
- false | 将find指令的回传值皆设为False; |
- fls<列表文件> | 此参数的效果和指定“ - ls”参数类似,但会把结果保存为指定的列表文件; |
- follow | 排除符号连接; |
- fprint<列表文件> | 此参数的效果和指定“ - print”参数类似,但会把结果保存成指定的列表文件; |
- fprint0<列表文件> | 此参数的效果和指定“ - print0”参数类似,但会把结果保存成指定的列表文件; |
- fprintf<列表文件><输出格式> | 此参数的效果和指定“ - printf”参数类似,但会把结果保存成指定的列表文件; |
- fstype<文件系统类型> | 只寻找该文件系统类型下的文件或目录; |
- gid<群组识别码> | 查找符合指定之群组识别码的文件或目录; |
- group<群组名称> | 查找符合指定之群组名称的文件或目录; |
- help或——help | 在线帮助; |
- ilname<范本样式> | 此参数的效果和指定“ - lname”参数类似,但忽略字符大小写的差别; |
- iname<范本样式> | 此参数的效果和指定“ - name”参数类似,但忽略字符大小写的差别; |
- inum<inode编号> | 查找符合指定的inode编号的文件或目录; |
- ipath<范本样式> | 此参数的效果和指定“ - path”参数类似,但忽略字符大小写的差别; |
- iregex<范本样式> | 此参数的效果和指定“ - regexe”参数类似,但忽略字符大小写的差别; |
- links<连接数目> | 查找符合指定的硬连接数目的文件或目录; |
- iname<范本样式> | 指定字符串作为寻找符号连接的范本样式; |
- ls | 假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出; |
- maxdepth<目录层级> | 设置最大目录层级; |
- mindepth<目录层级> | 设置最小目录层级; |
- mmin<分钟> | 查找在指定时间曾被更改过的文件或目录,单位以分钟计算; |
- mount | 此参数的效果和指定“ - xdev”相同; |
- mtime<24小时数> | 查找在指定时间曾被更改过的文件或目录,单位以24小时计算; |
- name<范本样式> | 指定字符串作为寻找文件或目录的范本样式; |
- newer<参考文件或目录> | 查找其更改时间较指定文件或目录的更改时间更接近现在的文件或目录; |
- nogroup | 找出不属于本地主机群组识别码的文件或目录; |
- noleaf | 不去考虑目录至少需拥有两个硬连接存在; |
- nouser | 找出不属于本地主机用户识别码的文件或目录; |
- ok<执行指令> | 此参数的效果和指定“ - exec”类似,但在执行指令之前会先询问用户,若回答“y”或“Y”,则放弃执行命令; |
- path<范本样式> | 指定字符串作为寻找目录的范本样式; |
- perm<权限数值> | 查找符合指定的权限数值的文件或目录; |
假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为每列一个名称,每个名称前皆有“. / ”字符串; | |
- print0 | 假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式为全部的名称皆在同一行; |
- printf<输出格式> | 假设find指令的回传值为Ture,就将文件或目录名称列出到标准输出。格式可以自行指定; |
- prune | 不寻找字符串作为寻找文件或目录的范本样式; |
-regex<范本样式> | 指定字符串作为寻找文件或目录的范本样式; |
- size<文件大小> | 查找符合指定的文件大小的文件; |
- true | 将find指令的回传值皆设为True; |
- type<文件类型> | 只寻找符合指定的文件类型的文件; |
- uid<用户识别码> | 查找符合指定的用户识别码的文件或目录; |
- used<日数> | 查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算; |
- user<拥有者名称> | 查找符和指定的拥有者名称的文件或目录; |
- version或——version | 显示版本信息; |
- xdev | 将范围局限在先行的文件系统中; |
- xtype<文件类型> | 此参数的效果和指定“ - type”参数类似,差别在于它针对符号连接检查。 |
2.1 示例:查找大于1MB的文件
find /path/to/search -type f -size +1M
上述命令将在指定路径下查找所有大小大于1MB的文件。
2.2 示例:查找最近7天内修改过的文件
find /path/to/search -mtime -7
这个例子将在指定路径下查找最近7天内修改过的文件。
2.3 示例:查找属主为user1的文件
find /path/to/search -user user1
上述命令将在指定路径下查找所有属主为user1的文件。
2.4 示例:执行自定义命令
find /path/to/search -name "*.log" -exec rm {} \;
这个例子将删除指定路径下所有扩展名为.log的文件。
3、高级用法
3.1 使用逻辑操作符
find命令支持逻辑操作符,如-a(与)、-o(或)、!(非),用于组合多个条件。
3.1.1 示例:查找大于1MB且是普通文件的文件
find /path/to/search -type f -size +1M -a -type f
上述命令将查找指定路径下所有大小大于1MB且是普通文件的文件。
3.1.2 示例:查找修改时间在7天之前或文件名以.bak结尾的文件
find /path/to/search \( -mtime +7 -o -name "*.bak" \)
这个例子将查找指定路径下修改时间在7天之前或文件名以.bak结尾的文件。
3.2 搜索多个路径
3.2.1 示例:查找多个目录下的所有文件
find /path/to/dir1 /path/to/dir2 -type f
上述命令将在dir1和dir2两个目录中查找所有文件。
3.3 将find结果用于其他命令
3.3.1 示例:在搜索结果中执行grep
find /path/to/search -type f -name "*.txt" -exec grep "pattern" {} \;
上述命令将在指定路径下所有扩展名为.txt的文件中搜索包含指定模式的行。
3.3.2 示例:将搜索结果输出到文件
find /path/to/search -type f -name "*.log" > logfiles.txt
这个例子将查找指定路径下所有扩展名为.log的文件,并将结果输出到名为logfiles.txt的文件中。
4、find命令的性能优化
在处理大量文件时,find命令的性能可能成为一个考虑因素。以下是一些建议用于提高性能的技巧:
-
尽量减少-exec选项的使用,因为每个匹配的文件都会执行一次命令。
-
使用-print选项代替-exec,将结果输出到标准输出,然后使用管道将结果传递给其他命令。
-
使用-maxdepth选项限制递归的深度,以减少搜索的范围。
4.案例实战
1.自动备份文件或目录:
#!/bin/bash
backup_dir="/path/to/backup/dir"
files_to_backup="/path/to/files /path/to/dir"
timestamp=$(date +%F_%T)
tar -czvf "${backup_dir}/backup_${timestamp}.tar.gz" ${files_to_backup}
2.批量重命名文件
#!/bin/bash
extension=".txt"
for file in *${extension}
do
filename=$(basename "${file}" "${extension}")
mv"${file}" "${filename}_new${extension}"
done
3.批量删除文件
#!/bin/bash
extension=".tmp"
for file in *${extension}
do
rm "${file}"
done
4.查找并删除指定名称的文件:
#!/bin/bash
search_string="old_string"
replace_string="new_string"
find . -type f -exec sed -i "s/${search_string}/${replace_string}/g"{}\;
~
5.查找并替换文件内容:
#!/bin/bash
# 设置要查找的字符串
search_string="old_string"
# 设置要替换成的字符串
replace_string="new_string"
# 查找并替换文件内容
find . -type f -exec sed -i "s/${search_string}/${replace_string}/g" {} \;
6.批量创建文件
#!/bin/bash
prefix="file"
num_files=10
for i in $(seq 1 ${num_files})
do
touch "${prefix}${i}.txt"
done
7.创建文件夹并移动文件
#!/bin/bash
dir_name="new_dir"
file_to_move=“file1.txt file2.txt"
mkdir ${dir_name} && mv ${files_to_move} ${dir_name}
8.在文件夹中查找文件:
#!/bin/bash
dir_path="/path/to/dir"
filename="example.txt"
find ${dir_path} -name "${filename}"
9.计算文件夹中文件数量:
#!/bin/bash
dir_path="/path/to/dir"
num_files=$(find ${dir_path} -type f | wc -l)
echo "Number of files in ${dir_path}: ${num_files}"
10.计算文件夹大小:
#!/bin/bash
dir_path="/path/to/dir"
dir_size=$(du -sh ${dir_path})
echo "Size of ${dir_path}: ${dir_size}"
11.定时执行命令:
#!/bin/bash
command="echo hello"
period=10
while true
do
eval ${command}
sleep ${period}
done
12.发送邮件:
#!/bin/bash
to="recipient@example.com"
from="sender@example.com"
subject="Test Email"
body="This is a test email."
echo "${body}" | mail -s "${subject}" -r "${from}" "${to}"
13.批量解压缩文件:
#!/bin/bash
extension=".tar.gz"
for file in *${extension}
do
tar -xvzf ${file}
done
~
14.在文件夹中查找并删除文件
#!/bin/bash
dir_path="/path/to/dir"
extension=".tmp"
find ${dir_path} -name "*${extension}" -delete
15.批量重命名文件:
#!/bin/bash
extension=".old"
new_extension=".new"
for file in *${extension}
do
filename=$(basename"${file}""${extension}")
mv "${file}" "${filename}${new_extension}"
done
~
16.对文件夹中的文件按修改时间排序:
#!/bin/bash
dir_path="/path/to/dir"
find ${dir_path} -type f -printf "%T@ %p\n" | sort -n
17.批量转换文件格式:
#!/bin/bash
extension=".txt"
new_extension=".md"
for file in *${extension}
do
pandoc -s "${file}" -o "${file/${extension}/${new_extension}}"
done
18.删除文件夹中的空文件夹:
#!/bin/bash
dir_path="/path/to/dir"
find ${dir_path} -type d -empty -delete
19.删除文件夹中的空文件:
#!/bin/bash
dir_path="/path/to/dir"
find ${dir_path} -type d -empty -delete
20.批量更改文件权限:
#!/bin/bash
dir_path="/path/to/dir"
premission="644"
find ${dir_path} -type f -exrc chmod ${permission}{}\;
21.使用awk分隔文件
#!/bin/bash
filename=$1
info=`awk -F " " '{printf "%-8s %-8s %-8s %-8s\n",$2.$4,$5,$6}' $filename`
printf "异常机器名称为 运营商为 异常地区 异常问题 \n$info"
echo -e " "