Linux——三、数据处理(正则、sed、awk)

一、正则使用

正则字符作用
^str查找在行首的字符串str
str$查找在行尾的字符串str
.除换行符\n外的任何单个字符
\转义符
*匹配前面的字符或子表达式 0-N次
+重复前面的字符或子表达式 1-N次
?重复前面的字符或子表达式 0-1次
[list]匹配中括号里的字符【注:q[wert] 表示的字符可以是qw、qe、qr、qt,即只要包含括号里的单个字符都匹配】
[^list]与[list]相反,表示不包含括号里的字符
str1|str2或,满足左右两个字符或两个表达式的字符串
{n,m}1. {n}:匹配前面一个字符或子表达式n次【必须n次,不能多不能少】
2.{n,}:匹配前面一个字符或子表达式至少n次
3.{n,m}:匹配…n到m次
()标记一个子表达式的开始和结束
[A-Z]和[a-z]分别表示所有大写字母和小写字母
[0-9]所有数字
\s匹配任何空白符,包括空格、制表符、换页符等
\S任何非空白字符
?=**exp1(?=exp2):**匹配exp2表达式前面的exp1表达式匹配的字符
?<=(?<=exp2)exp1 匹配exp2表达式后面的exp1表达式所匹配的字符
?!exp1(?!exp2) 匹配后面不是exp2表达式的exp1
?<!(?<!exp2)exp1 匹配前面不是exp2的exp1

示例文本:

[root@localhost ~]# cat regex_txt
lala
haha
heihei
yoyo

示例:

  1. 查找行首为l的:

    [root@localhost ~]# grep -n '^l' regex_txt
    1:lala
    
  2. 查找行尾为o的:

    [root@localhost ~]# grep -n 'o$' regex_txt
    4:yoyo
    
  3. 查找符合axa的字符,即两个a中间必须有一个字符的字符:

    [root@localhost ~]# grep -n 'a.a' regex_txt
    1:lala
    2:haha
    

已练习,不想列了 太懒了

二、sed工具

sed也是管道命令,可处理标准输入。可对数据进行替换、删除、新增和选取特定行功能。

语法:sed [选项] [操作]

选项:

-n: 只列出sed处理的那些行
-f: 后跟filename,可将sed操作写入到文件,通过-f执行
-r: 使用扩展正则语法(默认支持基础正则)
-i: 直接修改读取的文件内容,非仅仅输出到屏幕

操作:

[n1,n2] oper

n1和n2表示要操作的行数,oper为具体的操作行为,分为以下几点:

  • a

    新增,接新增的字符【新增到下一行】

  • c

    替换change。替换n1-n2间的行为指定内容

  • d

    删除。删除指定的[n1,n2]行

  • i

    插入。与a相同,但插入到当前的前一行

  • p

    打印。通常与 sed -n 搭配使用

  • s

    替换。可搭配正则

示例:

[root@localhost ~]# cat test.txt
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q

有以上一个文本。

2.1 删除

删除指定行数

# 删除/etc/passwd 3-6行
[root@localhost ~]# cat -n test.txt | sed '3,6d'
     1	a
     2	b
     7	g
     8	h
     9	i
    10	j
    11	k
    12	l
    13	m
    14	n
    15	o
    16	p
    17	q
# 删除3行以后
[root@localhost ~]# cat -n test.txt | sed '3,$d'
     1	a
     2	b
# 删除第3行
[root@localhost ~]# cat -n test.txt | sed '3d'
     1	a
     2	b
     4	d
     5	e
     6	f
     7	g
     8	h
     9	i
    10	j
    11	k
    12	l
    13	m
    14	n
    15	o
    16	p
    17	q

其中,3行以后用3,$d表示,$表示最后一行。

2.2 新增

分别在第二行后和第二行前加上 love u

[root@localhost ~]# cat -n test.txt | sed '2a love u'
     1	a
     2	b
love u
     3	c
     4	d
     5	e
     6	f
     7	g
     8	h
  [root@localhost ~]# cat -n test.txt | sed '2i love u'
     1	a
love u
     2	b
     3	c
     4	d
     5	e
     6	f
     7	g
     8	h
     # 新增多行
   [root@localhost ~]# cat -n test.txt | sed '2i love u\
> haha'
     1	a
love u
haha
     2	b
     3	c
     ....

2.3 替换

替换3到6行的内容为:love u

[root@localhost ~]# cat -n test.txt | sed '3,6c love u'
     1	a
     2	b
love u
     7	g
     8	h
     9	i
    10	j
    ....

2.4 打印

截取3,6行打印出来:

[root@localhost ~]# cat -n test.txt | sed -n '3,6p'
     3	c
     4	d
     5	e
     6	f

一定要加 -n 啊,不然就会额外打印出其他所有数据:

[root@localhost ~]# cat -n test.txt | sed '3,6p'
     1	a
     2	b
     3	c
     3	c
     4	d
     4	d
     5	e
     5	e
     6	f
     6	f
     7	g
    .....

2.5 直接替换指定字符

刚刚的 c 操作是替换指定行,那如果我只想替换指定的字符怎么办?就可以用 s 操作,它更像是查询->替换。

语法:

`sed ‘s/替换的字符/新字符/g’,当然,替换的字符可以使用正则进行匹配

将c替换为lala:

[root@localhost ~]# cat -n test.txt | sed 's/c/lala/g'
     1	a
     2	b
     3	lala
     4	d
     5	e
     6	f
     7	g
     8	h
     9	i
    10	j

2.6 直接修改原文件

使用-i就可以直接修改原文件:

a修改问heihei:

[root@localhost ~]#  sed -i  's/a/heihei/g' test.txt
[root@localhost ~]# cat test.txt
heihei
b
c
d
e
f
g
h

三、awk

awk倾向于将一行分成多个字段进行处理,一行内默认的字段分隔符为空格或TAB,适合处理小文本。

awk '条件类型1{操作1} 条件类型2{操作2}' filename

先看一个简单的例子:

打印last中的第1列和第2列

[root@localhost ~]# last | awk '{print $1 "\t" $2}'
root	pts/0
root	pts/0
root	pts/0
root	pts/1
root	pts/0
reboot	system
root	tty1
root	pts/1

一下就出来了,而之前用cut命令,按照空格分割,会因无法确定有多少个空格而无法准确的取到第2列值。awk由于默认按照空格或TAB分割,自动将一行拆分成多个字段,我们想打印哪个字段,就直接通过print n 就 可 以 , n就可以, nn就代表第n个字段,n从1开始。$0表示一整行数据

3.1 内置变量

  • NF

    每行的字段数

  • NR

    当前awk处理的第几行

  • FS

    当前输入字段分割字符,默认空格

  • RS

    输入记录分隔符 默认换行符,即每行作为一个单位进行处理,每行处理的分隔符为FS

  • OFS

    输出字段分隔符,默认空格

  • ORS

    输出记录分隔符,默认换行符

[root@localhost ~]# cat test.txt
heihei  hehe
b wo ai ni
c yo yo n n n
d
e
f
g

以上文本。

非变量要用双引号引起来

[root@localhost ~]# cat test.txt | awk '{print "当前行:"NR",字段数:"NF",分隔符:"FS}'
当前行:1,字段数:2,分隔符:
当前行:2,字段数:4,分隔符:
当前行:3,字段数:6,分隔符:
当前行:4,字段数:1,分隔符:
当前行:5,字段数:1,分隔符:
当前行:6,字段数:1,分隔符:
当前行:7,字段数:1,分隔符:

3.2 逻辑运算

包括:

>
<
>=
<=
==
!=

对/etc/passwd 按 冒号进行分割,找出第3列小于10的行,然后打印出第1和第3列:

[root@localhost ~]# cat /etc/passwd | awk '{FS=":"} $3<10 {print $1 "\t" $3}'
root:x:0:0:root:/root:/bin/bash
bin	1
daemon	2
adm	3
lp	4
sync	5
shutdown	6
halt	7
mail	8

但是,这里虽然指定了分隔符,但是只能作用在第2行和以后,第一行还是默认空格分割,如果想要第一行也被作用,需要使用BEGIN关键字:

[root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3<10 {print $1 "\t" $3}'
root	0
bin	1
daemon	2
adm	3
lp	4
sync	5
shutdown	6
halt	7
mail	8

第一行就列出来了。

同样还有END关键字

  • BEGIN

    awk会在读取任何输入行前执行BEGIN中指定的动作

  • END

    awk会在其退出前执行END指定的动作

    [root@localhost ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3>10 {print $1 "\t" $3} END {print $1}'
    operator	11
    games	12
    ftp	14
    nobody	99
    systemd-network	192
    dbus	81
    polkitd	999
    sshd	74
    postfix	89
    wangmaolin	1000
    wangmaolin
    

    在最后的时候打印出第一个变量

示例:

有如下文件:

[root@localhost ~]# cat cal.txt
col1 col2 col3
1    2    3
4    5   6
7  8  9

计算每列的和放到第4列:

[root@localhost ~]cat cal.txt | awk 'NR==1 {printf "%5s %5s %5s %5s\n", $1,$2,$3,"sum"}\
NR>=2 {printf "%5d %5d %5d %5d\n",$1,$2,$3,$1+$2+$3}'
 col1  col2  col3   sum
    1     2     3     6
    4     5     6    15
    7     8     9    24

指定输出分隔符:

[root@localhost ~]# cat cal.txt | awk 'BEGIN{OFS="---"} {print $1,$2,$3}'
col1---col2---col3
1---2---3
4---5---6
7---8---9

3.3 数组和循环

awk的数组看作python的字典,索引非索引,而是可理解为key,指定的key存放对应的value,key唯一,无序,使用for遍历时,是遍历的key,通过arr[key]可访问对应的值。

[root@localhost ~]# awk 'BEGIN {arr[1]=2
arr["a"] = 3
arr["haha"] = "heihei"
for(key in arr)
{
print arr[key]
}
}'
#结果:
3
heihei
2

删除元素也和python一样,delete arr[key]

[root@localhost ~]# awk 'BEGIN {arr[1]=2
arr["a"] = 3
arr["haha"] = "heihei"
for(item in arr)
{
print arr[item]
}
delete arr["a"]
print arr["a"]
}'
# 结果
3
heihei
2
    # 打印空白,说明删除了

3.4 通过文件调用awk 并传参

其他的,awk也支持标准的流程运算,函数等,因此我们可以把它看作一个 脚本,也因此,我们可以把awk命令直接写入文件,通过调用文件的方式执行awk操作。

awk -f awk脚本文件名 [赋值变量] 数据文件


[root@localhost ~]# cat awk_script
{print $n name}
# 调用脚本,并给变量赋值
[root@localhost ~]# awk -f awk_script n=2 name="test" cal.txt
col2test
2test
5test
8test

更多用法:

http://c.biancheng.net/view/4097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值