正则与sed,grep,awk三剑客
Posted samyoung
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则与sed,grep,awk三剑客相关的知识,希望对你有一定的参考价值。
系统登录顺序:
/etc/profile
/etc/profile.d/a.sh (a.sh自己建的)
/root/.bash_profile
/root/.bashrc
/etc/bashrc
/bin/bash 提供命令解释器(终端)
直接打/bin/bash 非登录shell
/root/.bashrc
/etc/bashrc
/etc/profile.d/a
可将别名alias等写入以上三个文件
正则表达式:
grep
-n 只显示行号
-o 只显示匹配内容
-q 安静模式,不打印 echo $? 为0显示输出正确
-l 过滤成功显示文件名,不成功无
-A 2 ‘root‘ /etc/passwd 过滤root所在后两行 (显示错误相关信息)
-B 5 ‘root‘ /etc/passwd 过滤root所在前5行
-C 如果匹配成功,则将匹配行及前后n行都打印出来 -color
-c 如果匹配成功,显示行数
-E egrep
-i 忽略大小写
-v 取反
-w 过滤单词,(不连贯)
-r 递归
^ 以开头的 ^b.n
* b* 前面字符 左面的一个字符0或无穷个 ab*
egrep + 一个或无穷个
ab{3} 匹配b三次
egrep -w ‘ab{3}‘ a.txt 匹配单词
egrep -w ‘ab{3}$‘ a.txt
‘ab{2,4}‘
? 左面字符出现0次或一次
root123
ROot ass
Root_123
r00ts
root 123
egrep
* 左面的一个字符有0个或无穷个
+ 左面的一个字符有1个或无穷个
? 左面的一个字符有0个或一个
{n} 左面的那个字符有n个 egrep -w ‘ab{3}$‘ a.txt
{n,m} 左边的字符n到m个
{n,} 左边的字符n个到无穷个
egrep r([abc123\/\-])t -必须放到最后去 -在数字后有指向性,如果想要匹配的字符就是-本身,必须放到最后去[12312\-]
egrep r[]
[] 定义好范围取一个
. 任意取一个
egrep r.t a.txt
egrep ‘[]‘
egrep ‘[a-zA-Z]‘ a.txt 所有英文字母的
跟‘r[aa-zz]t‘一样的
r[0-9]{2}t ===== r[0-9][0-9]t
‘r[0-9]+t‘ 数字有一个或无穷个
‘^[^0-9]‘ 开头取反 以非数字开头的
egrep ‘company(y|ies)‘ a.txt 或的关系
a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!sed -n 静态模式
sed -e 多个模式
sed -i ‘‘ test 输出到文件
sed -f ‘‘ 指定文件
sed ‘3d‘ test 删除第三行
sed ‘1,4d‘ test 删除1到4行
sed ‘1d;4d‘ test 删除1行和4行
sed ‘3p‘ test 打印第三行
sed -n ‘3p‘ test
sed ‘3c 1111‘ test 覆盖第三行
sed ‘3a 11111‘ test 第三行后追加一行
sed ‘3i 111‘ test 第三行前插入
sed ‘/sb.*$/d‘ a.txt 匹配0或没有 ======== sed ‘/sb/d‘ a.txt
sed ‘/^s/c 111‘ a.txt
sed ‘s/sb/SB/‘ test 只改每行遇到的第一个sb
sed ‘s/sb/SB/g‘ test 改所有的sb
sed ‘4s/sb/SB/g‘ test 只改所有的sb
sed ‘aa/sb/SB/g‘ test 把aa那行的sb改了
sed ‘/^[0-9][a-z]+sb$/s/sb/SB/g‘ test 匹配一行内容所有表达
sed -r ‘/^[0-9] ([a-Z]+)xsb$ /s/sb/SB/g‘ a.txt 扩展正则 匹配alexsb
sed -r ‘s///g‘ test 定位 /换的源/换的结果/g
sed -r ‘\3\2\1\4/g‘
sed -r ‘###‘
sed -ri ‘///‘
例子:
1.
root123
ROot ass
Root_123
r00ts
root 123
2.
root123
ROot ass
Root_123
r00ts
root 123
3.
a
ab
abb
abbb
abbbb
abbnbb
abbbbbbc
4.
r1t
r2t
r3t
r/t
r-t
r34t
r34352t
5.
[[email protected] tmp]# cat test
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
6.
12company12121
21321companiesafasf
7.
1rootsb
2tomsb
3egon
4alexsb
5wupeiqisb
6yuanhaosb
7sb
8sb2
awk
awk [ options ] ‘pattern {action}‘ file
awk 参数 模式(动作) file 模式即条件 动作就是干什么,由大括号里面一条或多条语句组成。
pattern 即模式,找谁 action 干啥
域和记录
filed 域,区域,字段,列
$0,整行,一个记录 $1 $2 $3 $NF最后一行 $0整行
$ 表示取
FS 区域分隔符 awk -F 记录字段分隔符的内容
NF 列的数量一行有多少列(区域)
head /etc/passwd > /servers/files/awkfile.txt
awk -F ":" ‘NR>=3&&NR<=5{print $1,$3}‘ /servers/files/a.txt
字段分隔符FS 指定的值可以是一个正则表达式(匹配字符串)
ifconfig eth1 | awk ‘NR==2{print $1}‘ 输出inet6 为第一列
ifconfig eth1 | awk -F "[: ]+" ‘NR==2{print $2}‘ 输出inet6 分割完变成第二列
RS 每个记录读入(输入)的时候的分隔符 上下分割每行
NR 行号 awk处理的记录的数
ORS 输出时候的分隔符
awk使用内置变量RS来存放记录分隔符,RS表示的输入的记录分隔符,之歌值可通过BEGIN模块重新定义修改。
awk ‘BEGIN{FS=":";RS="\n"}‘
awk ‘{print NR,$0}‘ 1.txt 显示行号
awk ‘BEGIN{RS="/"}{print NR,$0}‘ 1.txt
行:默认以回车换行\n,结束的.RS(行分隔符)RS表示着行的结束。
RS为空值
awk ‘BEGIN{RS=""}{print NR,$0}‘ 1.txt 只会显示一行行号
当RS值为空时,每个记录被空行或多个空行分割,同时无论FS分隔符为何值,FS同时也会被\n分割。
sed -r ‘s#[:/0-9]+# #g‘ awkfile.txt
sed -r ‘s#[:/0-9]+# #g‘ awkfile.txt >count.txt
sort 排序
sort 默认是升序,sort -r 降序
sort -u 去除重复行
uniq 去重
-i 忽略大小写字符
-c 进行计数
-u 只显示唯一的行
cut 从文件文件中截取
-d 后接分割字符
-f 依据-d的分隔符将信息分割成数段,-f 取出第几段
-c 以字符的单位取出固定字符区间
将 PATH 变量取出,我要找出第三和第五个路径。
#echo $PATH | cut -d ‘:‘ -f 3,5
/sbin:/usr/local/bin
将 PATH 变量取出,我要找出第三到最后一个路径。
echo $PATH | cut -d ‘:‘ -f 3-
/sbin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin:/usr/games
将 PATH 变量取出,我要找出第一到第三个路径。
#echo $PATH | cut -d ‘:‘ -f 1-3
/bin:/usr/bin:/sbin:
将 PATH 变量取出,我要找出第一到第三,还有第五个路径。
echo $PATH | cut -d ‘:‘ -f 1-3,5
/bin:/usr/bin:/sbin:/usr/local/bin
wc 统计
-l 仅取出列,统计行数
-w 仅列出多少字,统计单词出现次数
-m 多少字符,统计文件的字节数
wc /etc/passwd
40(行数) 45(单词数)1719(字节数)
求记录文件中每个单词的重复数量
egrep -o "[a-zA-Z]+" count.txt |sort |uniq -c
awk ‘BEGIN{RS=" |\n"}{print $0}‘ count.txt|sort |uniq -c 空格或换行符
awk 默认用\n 分割
正则表达式
实战准备
1.调整别名
alias grep=‘grep --color=auto‘
2.环境变量
locale
export LC_ALL=C
3.准备例子
vi /oldboy/old.log
I am oldboy teacher!
I teach linux
I like badminton ball,billiard ball and chinese chess!
my blog is http://oldboy.blog.51cto.com
our site is http://www.etiantian.org
my qq num is 49000448
not 4900000448
my god,i am not oldbey,but OLDBOY!
god
good
goood
gd
4. ^代表一行的开头
$代表一行的结尾
^$ 空行
. 代表任意一个字符
\ \. 就只代表点本身,转义符号,让有着特殊身份字符脱掉马甲,还原原型。 \$。
* 重复1个或多个前面的一个字符. o* :o oo ooooo等等
.* 匹配所有字符(0或没有)。^.*以任意多个字符开头,.*$以任意多个字符结尾。
(.) 任意一个字符grep正则
grep "." a.txt
grep "\." a.txt 匹配带.的
grep "oldb.y" a.txt
grep "\.$" a.txt 匹配以.结尾的
grep “.*” a.txt 匹配所有的
grep "." a.txt 匹配没有空行的
grep "^m" oldboy.log
grep -n "^$" 1.log 打印空行及行号
grep -vn "^$" 1.log 打印空行以外的及行号
-i 忽略大小写的不同
-c 计算搜索字符串的次数 3
-o 显示搜索的(只匹配输出) 3个m
-a 以文本文件的方式搜索数据
-n 对匹配的内容在其行首显示行号
--color=auto 以特定颜色亮显示匹配关键字
-C context,显示匹配字符串及其前后各num行
[abc] 匹配字符集合内的任意一个字符[a-zA-Z],[0-9] [a-z]所有小写字母 [A-Z]所有大写字母
[^abc] 匹配不包含^后的任意(任意一个)字符的内容
a\{n,m\} 重复n到m次,前一个重复的字符,如果用egrep/sed -r 可以去掉斜线
a\{n,\} 重复至少n次,前一个重复的字符。如果用egrep/sed -r 可以去掉斜线
a\{n\} 重复n次,前一个重复的字符。如果egrep/sed -r 可以去掉斜线
a\{,m\} 随便重复,但是不能超过m次
注意:egrep或sed -r 过滤一般特殊字符可以不转义
grep “0\{,3\}” oldboy.log
grep -E "0{,3}" oldboy.log
egrep "0{,3}" oldboy.log
5.扩展正则
必须用 grep -E 或egrep
(1)+ 重复一个或一个以上前面的字符(和基础正则*的区别) +要求重复数量至少为1,*可以为0,所以字符串为空也可以匹配
基础正则*是匹配0个或多个前面的那个字符
(2)?重复“0个或一个”前面的字符 (和基础正则.的区别)
(可以没有) 基础正则.是匹配有且只有一个字符,代表任意一个字符
(3)|用或的方式查符合多个条件的字符串
(4)()找出“用户组”字符串 分组过滤,后向引用
例子:
egrep "go+d" 1.txt
egrep "go*d" 1.txt
egrep "go?d" 1.txt
egrep "go.d" 1.txt
egrep "god|good" 1.txt
egrep "g(o|oo)d" 1.txt
\b 取出单词边界
grep "\boldboy\b" oldboy.log 只取出oldboy的,oldboy1不取出
6.sed
例子:
1.除了oldboy以外的
vi test.txt --
test
liyao
oldboy
五种方法:
grep -v oldboy test.txt
head -2 test.txt
sed ‘/oldboy/d’ test.txt / / 两个斜线之间表示要过滤的内容,d表示对过滤内容采取什么动作
sed -n /[^oldboy]/p test.txt
awk /[^oldboy]/ test.txt
2.查看ett.txt(100行)内第20到30行内容
seq 100>ett.txt
head 取头部的几行,默认前10行
1.head -30 ett.txt |tail -11 tail 取尾部的最后n行,默认后10行(tail 文件)
2.tail -81 ett.txt |tail -11
3.sed -n ‘20,30p‘ ett.txt
sed -n ‘30p‘ ett.txt 也可以用的
sed ‘2s/root/sb/g‘ 1.txt 改第二行所有root
sed ‘2s/root/sb/‘ 1.txt 改第二行第一个
awk
awk -F:‘{print $1,$4}‘ /etc/passwd 指定分隔符
$0 整行
NF 多少段 $NF 最后一段
NR 行号 (直接NR)
awk -F: ‘NR==1{print $1,NR}‘ test
awk -F: ‘NR<=3{print NR,"---"$1}‘ test ‘ " " ‘自己定义输出
‘NR>=3 && NR<=5{print NR,"-------",$1}‘ test
‘NR<=2 || NR>=7{print NR,"-------",$1}‘ test
‘/nologin$/{print $1}‘ test
‘$1~/^r.*t$/{print $3,NR}‘ tes
‘$3 >=7{print NR,$1}‘ test
count=7
awk -v x=$count -F: ‘$3 >= x{print NR,$1,$3}‘ test
UID大于等于x的打出来
ifocnifg |awk ‘NR==2{print $2}‘
cat a.txt |sort |uniq -c
cat test |cut -d: -f1
du -sh 统计文件大小
find / -type f (普通文件)
find / -name "*.txt"
find / -size +10M and -size -30M
dd if=/dev/zero of=/a.txt bs=20M count=1
grep -rl ‘root‘ /test 递归查询内容显示文件夹
shell
vi set-host.sh
read -p ‘please input your hostname:‘ name
hostnamectl set-hostname $name
yum -y install bc
scale浮点运算 bc百分率运算
0.71 根据小数点后面scale后移,如果三位移动3位
变量
set
env
echo $1
unset $1
echo $PWD 大写字母为系统变量
改用户 PS1
PS1=‘‘
全局变量:自己及多有人都能取到
运算
((2<10))
echo $?
0
x=2
y=2
[ $x -ge $y ]
echo $?
gt大于
lt小于
ge大于等于
le小于等于
eq等于
ne不等于
[ $x -gt $y -a $a -gt $b ]
[ $x -ge $y -o $a -le $b ]
+= 意思 x=$x+1
((x=x+3)) ====== x+=3
((i++)) 自增1
$((x+=1))
x=1
a=$((x+=1))
echo $a
mem_use=`free | awk ‘NR==3{print $2}‘`
mem_use=`free | awk ‘NR==3{print $3}‘`
echo "scale=2;$mem_use/$mem_total" |bc -l |cut -d . -f2
测试文件状态
-d 目录
-s 文件长度 > 0、非空
-f 正规文件
-w 可写
-r 可读
-x 可执行
-L 符号连接
-u 文件有 suid 位设置
= 两个字符串相等
!= 两个字符串不相等
-z 空串
-n 非空串
vi 1.sh
#!/bin/bash
var=‘/etc/init.d‘
var=‘/etc/passwd‘
if [ -d $var ]
then
echo "$var is dictionary"
elif [ -b $var ]
then
echo "$var is block"
elif [ -f $var ]
then
echo "$var is regular file"
else
echo ‘unknow‘
fi
if [ $x -eq 1 ];then echo ‘x is 1‘;fi
vi test.sh
#test.sh
echo $0
echo $1
echo $2
echo $3
echo ${11}
echo ‘$$‘ $$ 这个进程的pid
echo ‘$*‘ $* 所有的
echo ‘[email protected]‘ [email protected] 所有的
echo ‘$#‘ $# 总共多少个
echo ‘$?‘ $? 执行是否正确的输出
[[email protected] tmp]# ./test.sh 1 2 3 4 5 6 7 8 9 10 11
./test.sh
1
2
3
11
$$ 7800
$* 1 2 3 4 5 6 7 8 9 10 11
[email protected] 1 2 3 4 5 6 7 8 9 10 11
$# 11
$? 0
expr 1 + 2
expr 99 / 134
yum install bc -y 浮点运算
echo ‘scale=2;30/1000‘ | bc -l
free | awk ‘NR==2{print $2}‘
[ -x ] 文件属性
[ -d ] 文件
[ -s ] 文件存在并且非空
cp -a 1 2
#!/bin/bash
ps aux |grep nginx |grep -v ‘grep‘
if [ $? -ne 0 ]
then
systemctl start nginx
fi
以上是关于正则与sed,grep,awk三剑客的主要内容,如果未能解决你的问题,请参考以下文章