1、基础正则
1、stat /etc/hosts 取出年月日
#使用sed
[root@linux-87-01 ~]# stat /etc/hosts | sed -n '5,7p' | sed -r 's#^(.*: )(....)-(..)-(..) (.*)$#\2-\3-\4#g'
2023-05-27
2013-06-07
2023-04-21
#使用awk
[root@linux-87-01 ~]# stat /etc/hosts | awk 'NR>=5 && NR<=7' | awk -F'[: -]' '{print $3"-"$4"-"$5}'
2023-05-27
2013-06-07
2023-04-21
2、在/tmp/目录下查找所有以.log结尾的文件
#方法1
[root@linux-87-01 ~]# find /tmp -type f -name "*.log"
#方法2
[root@linux-87-01 ~]# find /tmp/ -type f | grep '\.log$'
#方法3
[root@linux-87-01 ~]# find /tmp/ -type f | sed -n '/\.log$/p'
#方法4
[root@linux-87-01 ~]# find /tmp/ -type f | awk '/\.log$/'
3、找出/etc/passwd中所有包含以a-e开头的行
#方法1
[root@linux-87-01 ~]# grep '^[a-e]' /etc/passwd
#方法2
[root@linux-87-01 ~]# sed -n '/^[a-e]/p' /etc/passwd
#方法3
[root@linux-87-01 ~]# awk '/^[a-e]/' /etc/passwd
#方法4
[root@linux-87-01 ~]# sed '/^[a-e]/!d' /etc/passwd
4、查找/etc/ssh/sshd_config文件以#开头的行
#方法1
[root@linux-87-01 ~]# grep '^#' /etc/ssh/sshd_config
#方法2
[root@linux-87-01 ~]# sed -n '/^#/p' /etc/ssh/sshd_config
#方法3
[root@linux-87-01 ~]# awk '/^#/' /etc/ssh/sshd_config
5、查找test.txt文件中以a开头或e结尾的单词
#方法1
[root@linux-87-01 ~]# grep -E '^a|e$' test.txt
#方法2
[root@linux-87-01 ~]# sed -n '/^a|e$/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/^a|e$/' test.txt
6、假设test.txt文件存放的是电话号码,找出美国电话号码格式的字符串,比如:(123)456-7890或者123-456-7890
#方法1
[root@linux-87-01 ~]# grep -E '\([0-9]{3}\)[0-9]{3}-[0-9]{4}|[0-9]{3}-[0-9]{3}-[0-9]{4}' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/\([0-9]{3}\)[0-9]{3}-[0-9]{4}|[0-9]{3}-[0-9]{3}-[0-9]{4}/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/\([0-9]{3}\)[0-9]{3}-[0-9]{4}|[0-9]{3}-[0-9]{3}-[0-9]{4}/' test.txt
7、查找一个文件包含IP地址的行,例如:192.168.1.1或者10.0.0.1
#方法1
[root@linux-87-01 ~]# egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ip.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/p' ip.txt
#方法3
[root@linux-87-01 ~]# awk '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/' ip.txt
这是粗略的方法。
#较为精确的正则
(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}
8、从一个文件中查找所有包含至少一个空格的行
#方法1
[root@linux-87-01 ~]# grep -E ' ' test.txt
#方法2
[root@linux-87-01 ~]# sed -n '/ /p' ip.txt
#方法3
[root@linux-87-01 ~]# awk '/ /' ip.txt
9、查找日志文件中包含error或warning的行
#方法1
[root@linux-87-01 ~]# grep -E 'error|warning' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/error|warning/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/error|warning/' test.txt
10、在一个文件中查找所有包含指定路径(/img或/www)的行
#方法1
[root@linux-87-01 ~]# grep -E '/img/|/www/' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/\/img\/|\/www\//p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/\/img\/|\/www\//' test.txt
11、查找/tmp/目录中,最近一周修改的文件
[root@linux-87-01 ~]# find /tmp/ -type f -mtime -7
12、过滤出/etc/profile中包含$UID的行
#方法1
[root@linux-87-01 ~]# grep '$UID' /etc/profile
或
[root@linux-87-01 ~]# grep "\$UID" /etc/profile
#方法2
[root@linux-87-01 ~]# sed -n '/$UID/p' /etc/profile
#方法3
[root@linux-87-01 ~]# awk '/\$UID/' /etc/profile
13、从一个配置文件中查找特定端口号的行(如,22、80端口)
#方法1
[root@linux-87-01 ~]# grep -Ew '22|80' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/22$|80$/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/22$|80$/' test.txt
14、找出目录中所有大小为1M或更大的文件
[root@linux-87-01 ~]# find /tmp/ -type f -size +1M
15、查找/var/log/目录中以.log结尾的文件,并复制到/tmp/目录中
#方法1
[root@linux-87-01 ~]# find /var/log/ -type f -name "*.log" | xargs cp -t /tmp/
#方法2
[root@linux-87-01 ~]# cp `find /var/log/ -type f -name "*.log"` /tmp/
#方法3:
[root@linux-87-01 ~]# find /var/log/ -type f -name "*.log" -exec cp -t /tmp/ {} \;
#方法4
[root@linux-87-01 ~]# find /var/log/ -type f -name "*.log" -exec cp {} /tmp/ \;
2、可能需要扩展正则
1、查找一个文件中所有以数字开头并且后面跟着至少一个非数字字符的字符串的行
#方法1
[root@linux-87-01 ~]# grep -E '^[0-9][^0-9]+' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/^[0-9][^0-9]+/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/^[0-9][^0-9]+/' test.txt
2、从一个文件中查找所有包含至少一个逗号和至少一个句号的记录
[root@linux-87-01 ~]# egrep ',.*\.' test.txt
3、在一个文件中查找以字母a开头并且后面跟着至少2个数字字符的单词
#方法1
[root@linux-87-01 ~]# grep -E '^a[0-9]{2,}' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/^a[0-9]{2,}/p' test.txt
#方法3
[root@linux-87-01 ~]# awk '/^a[0-9]{2,}/' test.txt
4、在一个文件中查找所以匹配日期和时间格式的字符串(年-月-日 时:分:秒)
[root@linux-87-01 ~]# grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' test.txt
其他,
\d perl正则中的[0-9]
\w perl正则中的[a-zA-Z_]
例如:
[root@linux-87-01 ~]# date +"%F" | grep -P '\d{4}'
5、在一个文件中查找所有以字母a或b开头并且后面至少跟着3个以上字母的字符串
#方法1
[root@linux-87-01 ~]# egrep '^[ab][a-z]{3,}' test.txt
#方法2
[root@linux-87-01 ~]# sed -nr '/^[ab][a-z]{3,}/p' test.txt
3、sed替换功能
1、找到一个文件中所有以数字开头的行,并将它们转换为以#开头的行(如,1、haha,改成:#1、haha)
[root@linux-87-01 ~]# sed '/^[0-9]/s@^@#@g' test.txt
2、找一个文件中所有包含连续的数字的行,并把它们替换为一个x字符
[root@linux-87-01 ~]# sed -r '/^[0-9]{2,}/s#^[0-9]+#x#g' test.txt
3、找到一个文件中所有以#开头的行,并把#删除
[root@linux-87-01 ~]# sed 's@^#@@g' test.txt
#或者
[root@linux-87-01 ~]# sed '/^#/s@^#@@g' test.txt
4、找到一个文件中所有以a结尾的单词,并把它们替换为e
[root@linux-87-01 ~]# sed '/a$/s@a$@e@g' test.txt
#或者
[root@linux-87-01 ~]# sed 's@a$@e@g' test.txt
5、找到一个文件中所有长度为3的单词,并删除
[root@linux-87-01 ~]# sed -r '/\b[a-zA-Z]{3}\b/d' test.txt
#或者
[root@linux-87-01 ~]# sed -r '/\b[a-zA-Z]{3}\b/s#\b[a-zA-Z]{3}##g' test.txt
6、在一个文件中,找到所有以数字0开头,并且后面跟着一个非0数字的行,并把它们替换为#开头的行
[root@linux-87-01 ~]# sed '/^0[^0]/s@^@#@g' test.txt
7、找到一个文件中所有包含两个连续的字母a的行,并把它们替换为一个a
[root@linux-87-01 ~]# sed '/aa/s#aa#a#g' test.txt
8、在一个文件中,找出包含邮箱地址的行,并把它们提取出来。
[root@linux-87-01 ~]# grep -E '[a-Z0-9]+@[a-z0-9]+\.(com|cn)' test.txt
9、找到一个文件中所有以数字结尾的单词,并删除
[root@linux-87-01 ~]# sed -r '/[a-Z]+[0-9]$/s#[a-Z]+[0-9]$##g' test.txt
10、找到一个文件中所有以字母t开头,其后面跟着两个数字的行号,并把它们替换为#开头的行
[root@linux-87-01 ~]# sed -r '/^t[0-9]{2}/s@^@#@g' test.txt
11、在一个文件中,找到以大写字母开头的所有单词,并将它们转换为小写
大小写字母转换
[root@linux-87-01 ~]# echo {a..z} | tr 'a-z' 'A-Z'
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
[root@linux-87-01 ~]#
U:转为大写
u:转为小写
[root@linux-87-01 ~]# sed -r 's#([a-z])#\U\1#g' test.txt
4、删除
1、删除文件每一行的第一个字符
[root@linux-87-01 ~]# sed 's#^.##g' test.txt
2、删除文件每一行的第二个字符
[root@linux-87-01 ~]# sed -r 's#^(.).#\1#g' test.txt
3、删除文件每一行的最后一个字符
[root@linux-87-01 ~]# sed 's#.$##g' test.txt
4、删除文件每一行的倒数 第二个字符
[root@linux-87-01 ~]# sed -r 's#.(.)$#\1#g' test.txt
5、删除文件每行的第二个单词
假设文件内容如下:
[root@linux-87-01 ~]# cat test.txt
hello world
this is banana
[root@linux-87-01 ~]#
把每行的第二个单词删除后,为:
hello
this banana
使用sed如下
[root@linux-87-01 ~]# sed -r 's#([a-zA-Z]+[^a-zA-Z]+)[a-zA-Z]+#\1#g' test.txt
6、删除文件每行的倒数第二个单词
[root@linux-87-01 ~]# sed -r 's#[a-zA-Z]+([^a-zA-Z]+[a-zA-Z]+)$#\1#g' test.txt
7、删除文件每行的最后一个单词
[root@linux-87-01 ~]# sed -r 's#([a-zA-Z]+[^a-zA-Z]+)[a-zA-Z]+$#\1#g' test.txt
#方法2
[root@linux-87-01 ~]# sed -r 's#[a-zA-Z]+$##g' test.txt
8、交换每行的第1个字符和第二个字符
[root@linux-87-01 ~]# sed -r 's#^(.)(.)#\2\1#g' test.txt
9、交换每行的第1个字符和第二个单词
[root@linux-87-01 ~]# sed -r 's#^(.)[a-zA-Z]+([^a-Z]+)([a-z]+)#\3\2\1#g' test.txt
10、交换每行的第1个单词和最后一个单词
比如:文件内容为:
my name is haha
交换第1个和最后1个单词,为:
haha name is my
[root@linux-87-01 ~]# sed -r 's#([a-Z]+)([^a-Z0-9]+)(.*)([^a-Z0-9]+)([a-Z]+)#\5\2\3\4\1#g' test.txt
11、删除一个文件中所有的数字
[root@linux-87-01 ~]# sed 's#[0-9]##g' test.txt
12、删除每一行开头的所有空格
[root@linux-87-01 ~]# sed -r 's#^[ ]+##g' test.txt
13、用制表符替换文件中出现的所有空格
制表符:就是Tab键,相当于8个空格,\t表示制表符
[root@linux-87-01 ~]# sed -r 's#\t# #g' test.txt
14、把所有大写字母用()括起来
[root@linux-87-01 ~]# sed -r 's#([A-Z])#(\1)#g' test.txt
15、打印每行3次
[root@linux-87-01 ~]# sed -n 'p;p;p' test.txt
#或者
[root@linux-87-01 ~]# sed 'p;p' test.txt
16、隔行删除
[root@linux-87-01 ~]# seq 5 | sed -n '1~2p'
1
3
5
[root@linux-87-01 ~]#
1~2p:从第1行开始,每次加2显示,也就1、3、5。。。
17、只显示每行的第一个单词
[root@linux-87-01 ~]# sed -r 's#([a-Z]+)(.*)#\1#g' test.txt
18、打印每行的第一个单词和第三个单词
比如:my name is haha,打印第一个单词和第三个单词,则为:my is
[root@linux-87-01 ~]# echo "my name is haha wawa " | sed -r 's#([a-Z]+)([^a-Z0-9]+[a-Z]+[^a-Z0-9]+)([a-Z]+)(.*)#\1 \3#g'
19、将格式为mm/yy/dd的日期转换成mm;yy;dd格式
[root@linux-87-01 ~]# echo "05/2023/28" | sed -r 's#([0-9]{2})/([0-9]{4})/([0-9]{2})#\1;\2;\3#g'
05;2023;28
[root@linux-87-01 ~]#
20、过滤出/etc/passwd中包含root或nobody的行
[root@linux-87-01 ~]# grep -E 'root|nobody' /etc/passwd
21、过滤出/etc/passwd中以root开头的行
[root@linux-87-01 ~]# grep -E '^root' /etc/passwd
22、在/etc/ssh/sshd_config中过滤出包含permitrootlogin或usedns的行(忽略大小写)
[root@linux-87-01 ~]# grep -iE 'permitrootlogin|usedns' /etc/ssh/sshd_config
23、取出/etc/passwd中以bash结尾的行
[root@linux-87-01 ~]# grep -E 'bash$' /etc/passwd
24、取出c:d:e:磁盘的名字
假设,df.txt文件内容如下:
Filesystem Size Used Mounted on
C:\ 20G 10g /mnt/c
D:\ 10G 5G /mnt/d
E:\ 5G 1G /mnt/e
取出c:d:e:磁盘的名字
[root@linux-87-01 ~]# egrep -io '[cde]:' df.txt
25、取出stat /etc/passwd中的0644这四位数
#方法1
[root@linux-87-01 ~]# stat /etc/passwd | sed -n '4p' | awk -F'[(/]' '{print $2}'
#方法2
[root@linux-87-01 ~]# stat /etc/passwd | sed -n '4p' | sed -r 's#^(.*)([0-9]{4})(/.*)#\2#g'
26、把所有从包含oldboy的行开始到包含lidao的行结束,把之间的数字删除
sed '/oldboy/,/lidao/s#[0-9]##g' 文件名
27、删除(不显示)文件中所有包含空行、注释行、或者仅包含空格的行
[root@linux-87-01 ~]# egrep -v '^$|^ +$|^#' test.txt