大数据学习笔记(六) -- linux的文本处理

版权声明:weixin_40247263的博客 https://blog.csdn.net/weixin_40247263/article/details/82824328

Table of Contents

 

cut

sort

wc

sed

awk


cut

[root@node001 ~]# cat grep.txt 
aaa bbb  ccc
111 222
xx yy zz
oo 
qq ttt wwx
88888
666
AA BB CC

以 空格为 分隔符,将每一行分为多列,然后显示第2列

[root@node001 ~]# cut -d' ' -f2 -s grep.txt 
bbb
222
yy

ttt
BB

注意第三行是 一个空格,之所以是空格是因为 我grep.txt中 第三行的 oo 后面加了一个空格,而 88888和666 这两行没有空格,所以这两行对应位置没有空格,上面用了 参数 s 代表没有 分隔符的行就不显示。如果我没有加上 -s 参数,那么 88888和666也会被显示出来,如下

[root@node001 ~]# cut -d' ' -f2 grep.txt 
bbb
222
yy

ttt
88888
666
BB

sort

[root@node001 ~]# cat sort.txt 
banana 12
apple 1
orange 8

[root@node001 ~]# sort sort.txt 

apple 1
banana 12
orange 8
[root@node001 ~]# sort -t' ' -k2 sort.txt 

apple 1
banana 12
orange 8
[root@node001 ~]# sort -t' ' -k2 -n sort.txt 

apple 1
orange 8
banana 12
[root@node001 ~]# sort -t' ' -k2 -n -r sort.txt 
banana 12
orange 8
apple 1


wc

[root@node001 ~]# cat grep.txt 
aaa bbb  ccc
111 222
xx yy zz
oo 
qq ttt wwx
88888
666
AA BB CC
[root@node001 ~]# wc grep.txt  
 8 17 64 grep.txt

wc 命令 默认输出的为 文件的行数、单词数、以及字符数

也可通过参数指定查询某项内容

[root@node001 ~]# wc -m grep.txt 
64 grep.txt
[root@node001 ~]# wc -c grep.txt 
64 grep.txt
[root@node001 ~]# wc -l grep.txt 
8 grep.txt
[root@node001 ~]# wc -L grep.txt 
12 grep.txt
[root@node001 ~]# wc -w grep.txt 
17 grep.txt

sed

 

 例一

-n 只显示 符合条件的行,p和数字结合来筛选出指定行。

[root@node001 ~]# cat sort.txt 
banana 12
apple 1
orange 8

[root@node001 ~]# sed -n "2p" sort.txt 
apple 1
[root@node001 ~]# sed "3p" sort.txt 
banana 12
apple 1
orange 8
orange 8

例二

-i 会根据后面给出的命令 ,对源文件做对应操作, d和数字结合 代表删除指定行,如果不确定的话可以先去掉-i 看效果 

[root@node001 ~]# sed -i "3d" sort.txt 
[root@node001 ~]# cat sort.txt 
banana 12
apple 1

例三

2a代表在第二行的后面追加一行然后插入内容 

[root@node001 ~]# sed "2a\orange 8" sort.txt 
banana 12
apple 1
orange 8
[root@node001 ~]# sed -i "2a\orange 8" sort.txt 
[root@node001 ~]# cat sort.txt 
banana 12
apple 1
orange 8

例四

 /apple 查找到apple这个字符串,然后 i 代表在其上面追加一行 ,内容为 hello zzh

[root@node001 ~]# sed "/apple/i\hello zzh" sort.txt 
banana 12
hello zzh
apple 1
orange 8
[root@node001 ~]# sed -i "/apple/i\hello zzh" sort.txt 
[root@node001 ~]# cat sort.txt 
banana 12
hello zzh
apple 1
orange 8

例五

/^h  代表匹配当以字母h开头的行,d 代表删除。 

[root@node001 ~]# sed "/^h/d" sort.txt 
banana 12
apple 1
orange 8
[root@node001 ~]# sed -i "/^h/d" sort.txt 
[root@node001 ~]# cat sort.txt 
banana 12
apple 1
orange 8

例六

我们先cp 一个文件到 用户目录

[root@node001 ~]# cp /etc/inittab  ./
[root@node001 ~]# ll
total 24
-rw-r--r--. 1 root root  175 Sep 21 22:37 grep
-rw-r--r--. 1 root root   65 Sep 21 23:48 grep.txt
-rw-r--r--. 1 root root  884 Sep 22 00:09 inittab
-rw-r--r--. 1 root root 1796 Sep 21 20:20 profile
-rw-r--r--. 1 root root   28 Sep 22 00:09 sort.txt
-rw-r--r--. 1 root root   22 Sep 21 20:25 zzh.txt
[root@node001 ~]# tail inittab 
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:3:initdefault:

然后 将 最后一行的  3  改为 5

s 代表查找并替换,  s/被替换的字符/替换的字符      

s/ 后面是一个正则表达式,用小括号把 "id:" 和 ":initdefault:"  括住, 为了在后面使用 \1 和 \2 引用 

[root@node001 ~]# sed "s/\(id:\)[0-6]\(:initdefault:\)/\15\2/" inittab 

结果如下 

# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:5:initdefault:

例七

cp 一个网络配置文件

cp /etc/sysconfig/network-scripts/ifcfg-eth0 ./

 设置一个变量值

num=88

正则匹配ip地址然后将最后一位更改为88 

sed "s/\(IPADDR=\(\<2[0-5][0-5]\|\<2[0-4][0-9]\|\<1\?[0-9][0-9]\?\.\)\{3\}\).*/\1$num/" 

 结果如下

ifcfg-eth0 
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
IPADDR=192.168.46.88
NETMASK=255.255.255.0
GATEWAY=192.168.46.2
DNS1=114.114.114.114

awk

例一

cp 一个文件 

cp /etc/passwd ./

 以 “:” 分割文件中的每一行,并在读取文件之前输出  name        shell    在读取文件之后输出   hello  zzh

{} 花括号代表匿名函数,awk以行的粒度去读取文件,读出一行就会调用匿名函数,将读出的行信息传入匿名函数中,并执行代码, BEGIN 和 END  是固定的函数,一个是读取文件之前调用,一个是读取文件之后调用。

匿名函数可以有多个。BEGIN 和 END只能执行一次。

$1 代表取出第一列,$7 代表取出第七列,$0 代表取出整行

awk 所执行的函数 只能用 单引号 括住,因为 $ 对于bash来说是一个命令,用来取值。 

[root@node001 ~]# awk -F':' 'BEGIN{print "name\tshell"} {print $1 "\t" $7} {print $0} END{ print "hello zzh"}' passwd
name	shell
root	/bin/bash
root:x:0:0:root:/root:/bin/bash
bin	/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
daemon	/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm	/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp	/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync	/bin/sync
sync:x:5:0:sync:/sbin:/bin/sync
shutdown	/sbin/shutdown
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt	/sbin/halt
halt:x:7:0:halt:/sbin:/sbin/halt
mail	/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp	/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator	/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games	/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher	/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp	/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody	/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa	/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
saslauth	/sbin/nologin
saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
postfix	/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd	/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
god	/bin/bash
god:x:500:500::/home/god:/bin/bash
good	/bin/bash
good:x:501:501::/home/good:/bin/bash
zzh	/bin/bash
zzh:x:502:502::/home/zzh:/bin/bash
hello zzh
[root@node001 ~]# awk '/root/ {print $0}' passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

例二: 

查找文件中包含 root 字符串的行 并显示

[root@node001 ~]# awk '/root/ {print $0}' passwd 
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

例三

打印所有行,并显示行数和每行的列数

[root@node001 ~]# awk -F':' '{print NR"\t"NF"\t"$0}' passwd
1	7	root:x:0:0:root:/root:/bin/bash
2	7	bin:x:1:1:bin:/bin:/sbin/nologin
3	7	daemon:x:2:2:daemon:/sbin:/sbin/nologin
4	7	adm:x:3:4:adm:/var/adm:/sbin/nologin
5	7	lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6	7	sync:x:5:0:sync:/sbin:/bin/sync
7	7	shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8	7	halt:x:7:0:halt:/sbin:/sbin/halt
9	7	mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10	7	uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
11	7	operator:x:11:0:operator:/root:/sbin/nologin
12	7	games:x:12:100:games:/usr/games:/sbin/nologin
13	7	gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
14	7	ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
15	7	nobody:x:99:99:Nobody:/:/sbin/nologin
16	7	vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
17	7	saslauth:x:499:76:"Saslauthd user":/var/empty/saslauth:/sbin/nologin
18	7	postfix:x:89:89::/var/spool/postfix:/sbin/nologin
19	7	sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
20	7	god:x:500:500::/home/god:/bin/bash
21	7	good:x:501:501::/home/good:/bin/bash
22	7	zzh:x:502:502::/home/zzh:/bin/bash

例四

首先准备一个报表

[root@node001 ~]# cat awk.txt 
Tom	0	2012-12-11	car	3000
John    1	2013-01-13	bike    1000
vivi	1	2013-01-18	car	2800
Tom	0	2013-01-20	car	2500
John	1	2013-01-28	bike	3500

使用awk实现合计每人一月份的工资

split函数 对字符串以指定字符进行拆分,$3 对第三列进行拆分,date拆分以后存入date,以 "-" 进行拆分。

name[$1]+=$5  可以理解为  name[$1]=0  ;  name[$1] = name[$1]+$5

[root@node001 ~]# awk '{ split($3,date,"-");if(date[2]=="01"){name[$1]+=$5}} END{for(i in name){print i "\t" name[i]}}' awk.txt 
vivi	2800
Tom	2500
John	4500

例五

根据列四的案例,再增加一列显示员工的职位,制表符中的0代表Manger,1代表Worker,以下简写成M 和 W

[root@node001 ~]# awk '{ split($3,date,"-");if(date[2]=="01"){name[$1]+=$5;if($2=="0"){role[$1]="M"}else{role[$1]="W"}}} END{for(i in name){print i "\t" name[i] "\t" role[i]}}' awk.txt 
vivi	2800	W
Tom	2500	M
John	4500	W

列六

上面的写法当 命令过长时非常反人类,我们看起来非常不直观,其实可以将上面的内容写在一个文件当中,如下

[root@node001 ~]# cat command.awk 
{ 
	split($3,date,"-");
	if(date[2]=="01"){
		
		name[$1]+=$5;
		
		if($2=="0"){
			role[$1]="M";
		}else{
			role[$1]="W";
		}
		
	}
} 
END{
	for(i in name){
		print i "\t" name[i] "\t" role[i];
	}
} 

然后再使用 -f 参数执行

[root@node001 ~]# awk -f command.awk awk.txt 
vivi	2800	W
Tom	2500	M
John	4500	W

猜你喜欢

转载自blog.csdn.net/weixin_40247263/article/details/82824328