Fork me on GitHub

Linux| 05文本操作 (cut sed awk sort)

正则表达式与文本搜索

元字符

  • . 匹配除换行符外的任意单个字符;
  • * 匹配任意一个跟在它前面的字符;
  • [ ] 匹配方括号中的字符类中的任意一个;
  • ^ 匹配开头;
  • $ 匹配结尾;
  • \ 转义后面的特殊字符;
[root@Linux100 ~]# grep password /root/anaconda-ks.cfg
# Root password
[root@Linux100 ~]# grep pass.... /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 ~]# grep pass....$ /root/anaconda-ks.cfg
# Root password
[root@Linux100 ~]# 
[root@Linux100 ~]# grep pass.* /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 ~]# grep pass.*$ /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password

[root@Linux100 ~]# [Hh]ello hello Hello
bash: [Hh]ello: 未找到命令...
[root@Linux100 ~]# 
[root@Linux100 ~]# grep ^# anaconda-ks.cfg
#version=DEVEL
# System authorization information
# Use CDROM installation media
# Use graphical install
# Run the Setup Agent on first boot
# Keyboard layouts
# System language
# Network information
# Root password
# System services
# System timezone
# X Window System configuration information
# System bootloader configuration
# Partition clearing information
# Disk partitioning information
[root@Linux100 ~]# grep "\." anaconda-ks.cfg
lang zh_CN.UTF-8
part pv.252 --fstype="lvmpv" --ondisk=sda --size=50175
volgroup centos --pesize=4096 pv.252

扩展元字符

  •  + 匹配前面的正则表达式至少出现一次;
  •  ? 匹配前面的正则表达式出现零次或一次;
  •  | 匹配它前面或后面的正则表达式;

 

文件的查找命令find

  • find 路径 查找条件 [ 补充条件 ]

文本内容的过滤(查找)grep 

正则表达式的匹配方式

字符串 Do one thing at a time, and do well.

匹配字符 an 

 

[root@Linux100 etc]# cd /etc/
[root@Linux100 etc]# find passwd
passwd
[root@Linux100 etc]# ls passwd*
passwd  passwd-
[root@Linux100 etc]#  find /etc/ -name passwd
/etc/passwd
/etc/pam.d/passwd
[root@Linux100 etc]#  find /etc/ -name pass*
find: 路径必须在表达式之前: passwd-
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
[root@Linux100 etc]#  find /etc/ -name passwd*
find: 路径必须在表达式之前: passwd-
用法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
[root@Linux100 etc]# 
[root@Linux100 etc]# man find
[root@Linux100 etc]# 
[root@Linux100 etc]# find /etc -regex .*wd
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc -regex .*wd$
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc -regex .etc.*wd$
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# find /etc/ -type f -regex .*wd
/etc/passwd
/etc/security/opasswd
/etc/pam.d/passwd
[root@Linux100 etc]# cd 
[root@Linux100 ~]# 
[root@Linux100 ~]# echo 123 > file
[root@Linux100 ~]# stat file 
  文件:"file"
  大小:4             块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:67155058    硬链接:1
权限:(0644/-rw-r--r--)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:admin_home_t:s0
最近访问:2022-10-01 14:15:47.328060474 +0800
最近更改:2022-10-01 14:15:47.328060474 +0800
最近改动:2022-10-01 14:15:47.328060474 +0800
创建时间:-
[root@Linux100 ~]# LANG=C stat file 
  File: 'file'
  Size: 4             Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 67155058    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:15:47.328060474 +0800
Modify: 2022-10-01 14:15:47.328060474 +0800
Change: 2022-10-01 14:15:47.328060474 +0800
 Birth: -
[root@Linux100 ~]# touch file
[root@Linux100 ~]# LANG=C stat file 
  File: 'file'
  Size: 4             Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 67155058    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:16:48.992057117 +0800
Change: 2022-10-01 14:16:48.992057117 +0800
 Birth: -
[root@Linux100 ~]# 
[root@Linux100 ~]# chmod 755 file 
[root@Linux100 ~]# LANG=C stat file 
  File: 'file'
  Size: 4             Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 67155058    Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:16:48.992057117 +0800
Change: 2022-10-01 14:17:08.354056063 +0800
 Birth: -
[root@Linux100 ~]# echo 123456 >> file
[root@Linux100 ~]# LANG=C stat file 
  File: 'file'
  Size: 11            Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 67155058    Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-10-01 14:16:48.992057117 +0800
Modify: 2022-10-01 14:17:30.335054866 +0800
Change: 2022-10-01 14:17:30.335054866 +0800
 Birth: -
[root@Linux100 ~]# mkdir tmp
[root@Linux100 ~]# cd tmp/
[root@Linux100 tmp]# touch {1..9}.txt
[root@Linux100 tmp]# ls
1.txt  2.txt  3.txt  4.txt  5.txt  6.txt  7.txt  8.txt  9.txt
[root@Linux100 tmp]# find *.txt
1.txt
2.txt
3.txt
4.txt
5.txt
6.txt
7.txt
8.txt
9.txt
[root@Linux100 tmp]# find *txt -exec rm -v {} \;
已删除"1.txt"
已删除"2.txt"
已删除"3.txt"
已删除"4.txt"
已删除"5.txt"
已删除"6.txt"
已删除"7.txt"
已删除"8.txt"
已删除"9.txt"
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg
auth --enableshadow --passalgo=sha512
# Root password
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 1
auth
#
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 2
--enableshadow
Root
[root@Linux100 tmp]# grep pass /root/anaconda-ks.cfg | cut -d " " -f 3
--passalgo=sha512
password
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
/sbin/halt
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/bash
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | uniq -c
      1 /bin/bash
      4 /sbin/nologin
      1 /bin/sync
      1 /sbin/shutdown
      1 /sbin/halt
     34 /sbin/nologin
      1 /bin/bash
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort  uniq -c
sort: 打开失败: uniq: 没有那个文件或目录
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort | uniq -c
      2 /bin/bash
      1 /bin/sync
      1 /sbin/halt
     38 /sbin/nologin
      1 /sbin/shutdown
[root@Linux100 tmp]# cut -d ":" -f 7 /etc/passwd | sort | uniq -c | sort -r
     38 /sbin/nologin
      2 /bin/bash
      1 /sbin/shutdown
      1 /sbin/halt
      1 /bin/sync

set 和awk 

行编辑器介绍 

  • Vim和 sed、 AWK的区别;
  • sed的基本用法演示;
  • AWK的基本用法演示;

Vim和 sed、 AWK的区别:

  • 交互式与非交互式;( vim编辑器交互式,set、awk是非交互式 )
  • 文件操作模式与行操作模式;

sed 基本用法

sed 一般用于对文本内容做替换

   sed '/user1/s/user1/u1'  /etc/passwd 

AWK基本用法

AWK一般用于对文本内容进行统计、按需要的格式进行输出

  • cut 命令: cut -d : -f 1 /etc/passwd
  • AWK命令: awk -F : '/wd$/{print$1}'  /etc/passwd 

sed的替换命令

① sed的模式空间

sed的基本工作方式是:

  • 将文件以行为单位读取到内存(模式空间);
  • 使用sed的每个脚本对该行进行操作;
  • 处理完成后输出该行;

 

② 替换命令s

  • sed 's/old/new/' filename
  • sed -e 's/old/new/' -e 's/old/new/'  filename  ...
  • sed -i 's/old/new/'  's/old/new/'  filename  ...

带正则表达式的替换命令s:

  • sed 's/正则表达式/new/'  filename
  • sed -r 's/扩展正则表达式/new/'  filename 

 

[root@Linux100 tmp]# ls
[root@Linux100 tmp]# echo a a a > afile
[root@Linux100 tmp]# 
[root@Linux100 tmp]# sed 's/a/aa/' afile
aa a a
[root@Linux100 tmp]# sed 's!/!abc!' afile
a a a
[root@Linux100 tmp]# sed -e 's/a/aa/' -e 's/aa/bb/' afile 
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile bfile cfile
bb a a
sed:无法读取 bfile:没有那个文件或目录
sed:无法读取 cfile:没有那个文件或目录

[root@Linux100 tmp]# cat afile 
a a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile
bb a a
[root@Linux100 tmp]# sed -i 's/a/aa/;s/aa/bb/' afile
[root@Linux100 tmp]# cat afile 
bb a a
[root@Linux100 tmp]# sed 's/a/aa/;s/aa/bb/' afile > bfile
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# head -5 /etc/passwd
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
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/...//'
t:x:0:0:root:/root:/bin/bash
:x:1:1:bin:/bin:/sbin/nologin
mon:x:2:2:daemon:/sbin:/sbin/nologin
:x:3:4:adm:/var/adm:/sbin/nologin
x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@Linux100 tmp]# 
# s*bin/表示s出现一次或者0次 bin 
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/s*bin//'
root:x:0:0:root:/root://bash
:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/:/sbin/nologin
adm:x:3:4:adm:/var/adm://nologin
lp:x:4:7:lp:/var/spool/lpd://nologin


[root@Linux100 tmp]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@Linux100 tmp]# 
[root@Linux100 tmp]# grep root /etc/passwd | sed 's/^root//'
:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin



扩展元字符
[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
# b出现一次或者0次
[root@Linux100 tmp]# sed 's/ab*/!/' bfile 
b
!
!a
!aa
!
!
!

[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
# ?表前面出现0次或1次 
[root@Linux100 tmp]# sed -r 's/ab+/!/' bfile 
b
a
aa
aaa
!
!
!

[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
# 匹配a 或 b
[root@Linux100 tmp]# sed -r 's/a|b/!/' bfile 
!
!
!a
!aa
!b
!bb
!bbb
# ()分组 
[root@Linux100 tmp]# sed -r 's/(aa)|(bb)/!/' bfile 
b
a
!
!a
ab
a!
a!b



#回调功能 
[root@Linux100 tmp]# cat cfile 
axyzb
[root@Linux100 tmp]# sed -r 's/(a.*b)/\1:\1/' cfile
axyzb:axyzb

sed的替换命令加强版

全局替换 

s/old/new/g 

  • g为全局替换;
  • 用于替换所有出现的次数;
  • / 如果和正则匹配的内容冲突可以使用其他符合,如 s@old@new@g 

标志位

s/old/new/标志位 

  • 数字,第n次出现才替换;
  • g,每次出现都进行替换;
  • p 打印模式空间的内容: sed -n 'script' filename 阻止默认输出;
  • w file 将模式空间的内容写入到文件;

寻址

  • 默认对每行进行操作,增加寻址后对匹配的行进行操作;
  •  /正则表达式/s/old/new/g
  • 行内s/old/new/g,行号可以是具体的行,也可以是最后一行$符号;
  • 可以使用两个寻址符号,也可以混合使用行号和正则地址;

分组

  • 寻址可以匹配多条命令
  • /regular/{s/old/new/;s/old/new/} 

sed脚本文件

  • 可以将选项保存为文件,使用-f 加载脚本文件;
  • sed -f sedscript filename
[root@Linux100 tmp]# head -5 /etc/passwd
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
[root@Linux100 tmp]# 
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/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
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/g'
!!!!:x:0:0:!!!!:/!!!!:/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
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/2'
root:x:0:0:!!!!:/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
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# head -5 /etc/passwd | sed 's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash
!!!!: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
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n  's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash

[root@Linux100 tmp]# vim /root/a
anaconda-ks.cfg      anaconda-ks.cfg.bak  a.sh                 a.txt                
[root@Linux100 tmp]# vim /root/a.txt 
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n  's/root/!!!!/p'
!!!!:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n  's/root/!!!!/w /root.a.txt'
[root@Linux100 tmp]# cat /root/a.txt 
1.sh
2.sh
3.sh
4.sh
5.sh
anaconda-ks.cfg
a.sh
a.txt
b.txt
c.txt
d.txt
initial-setup-ks.cfg
mbr2.bin
mbr.bin
[root@Linux100 tmp]# head -5 /etc/passwd | sed -n  's/root/!!!!/w /root/a.txt'
[root@Linux100 tmp]# cat /root/a.txt 
!!!!:x:0:0:root:/root:/bin/bash





[root@Linux100 tmp]# head -6 /etc/passwd
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
[root@Linux100 tmp]# head -6 /etc/passwd | sed 's/adm/!/
> '
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!: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
[root@Linux100 tmp]# head -6 /etc/passwd | sed 's/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!: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
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1s/adm/!/'
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
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1,3s/adm/!/'
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
[root@Linux100 tmp]# head -6 /etc/passwd | sed '1,$s/adm/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
!: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
[root@Linux100 tmp]# head -6 /etc/passwd | sed 'root/s/bash/!/'
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
[root@Linux100 tmp]# head -6 /etc/passwd | sed '2s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
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
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
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
[root@Linux100 tmp]# 
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/!
adm:x:3:4:adm:/var/adm:/sbin/!
lp:x:4:7:lp:/var/spool/lpd:/sbin/!
sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/g'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/!
daemon:x:2:2:daemon:/sbin:/sbin/!
adm:x:3:4:adm:/var/adm:/sbin/!
lp:x:4:7:lp:/var/spool/lpd:/sbin/!
sync:x:5:0:sync:/sbin:/bin/sync

 sed其他指令

删除命令;

 [寻址] d 

  • 删除模式空间内容,改变脚本的控制流,读取新的输入行;
[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/d' bfile 
b
a
aa
aaa
[root@Linux100 tmp]# sed '/ab/d;s/a/!/' bfile 
b
!
!a
!aa

# 输出行号
[root@Linux100 tmp]# sed '/ab/d;=' bfile 
1
b
2
a
3
aa
4
aaa

追加、插入和更改;

  • 追加命令 a ;
  • 插入命令 i ;
  • 更改命令 c ;
[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/i hello' bfile 
b
a
aa
aaa
hello
ab
hello
abb
hello
abbb
[root@Linux100 tmp]# sed '/ab/a hello' bfile 
b
a
aa
aaa
ab
hello
abb
hello
abbb
hello
[root@Linux100 tmp]# sed '/ab/c hello' bfile 
b
a
aa
aaa
hello
hello
hello
[root@Linux100 tmp]# sed '/ab/r afile' bfile 
b
a
aa
aaa
ab
bb a a
abb
bb a a
abbb
bb a a
[root@Linux100 tmp]# sed '/ab/r afile' bfile > rfile

打印;

  • 打印命令p 

下一行;

  • 下一行命令 n
  • 打印行号命令 = 

读文件和写文件;

  • 读文件命令 r
  • 写文件命令 w

退出命令q

  • 哪个效率会更高呢?
    • sed 10q  filename  (它更高)
    • sed -n 1,10p filename 
[root@Linux100 tmp]# cat bfile 
b
a
aa
aaa
ab
abb
abbb
[root@Linux100 tmp]# sed '/ab/p' bfile 
b
a
aa
aaa
ab
ab
abb
abb
abbb
abbb
[root@Linux100 tmp]# sed -n '/ab/p' bfile 
ab
abb
abbb
[root@Linux100 tmp]# seq 1 10
1
2
3
4
5
6
7
8
9
10
[root@Linux100 tmp]# seq 1 10000 > lines.txt
[root@Linux100 tmp]# wc -l lines.txt 
10000 lines.txt



[root@Linux100 tmp]# sed -n '1,10p' lines.txt 
1
2
3
4
5
6
7
8
9
10

[root@Linux100 tmp]# time sed -n '1,10p' lines.txt 
1
2
3
4
5
6
7
8
9
10

real    0m0.002s
user    0m0.000s
sys    0m0.002s

[root@Linux100 tmp]# time sed -n '10p' lines.txt 
10

real    0m0.002s
user    0m0.000s
sys    0m0.002s

sed多行模式空间

sed的多行模式

为什么要有多行模式?

  • 配置文件一般为单行出现;
  • 也有使用XML或JSON格式的配置文件,为多行出现;

多行模式处理命令N、 D、 P

  • N 将下一行加入到模式空间;
  • D 删除模式空间中的第一个字符到第一个换行符;
  • P 打印模式空间中的第一个字符到第一个换行符;
[root@Linux100 tmp]# vim a.txt
[root@Linux100 tmp]# sed 'N' a.txt 
hel
lo

[root@Linux100 tmp]# sed 'N;s/hello/!!!/' a.txt 
hel
lo
[root@Linux100 tmp]# sed 'N;s/hel\nlo/!!!/' a.txt 
!!!
[root@Linux100 tmp]# sed 'N;s/hel.lo/!!!/' a.txt 
!!!



[root@Linux100 tmp]# cat > b.txt << EOF
> hell
> o bash hel
> lo bash
> EOF
[root@Linux100 tmp]# cat b.txt 
hell
o bash hel
lo bash
[root@Linux100 tmp]# sed 'N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt 
hello sed
 hello sed

[root@Linux100 tmp]# sed 'N;N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt 
hello sed
 hel
lo bash

保持空间

  • 保持空间也是多行的一种操作方式
  • 将内容暂存在保持空间,便于做多行处理

 

保持空间命令

  • h和H将模式空间内容存放到保持空间
  • g和G将保持空间内容取出到模式空间
  • x交换模式空间和保持空间内容
[root@Linux100 tmp]# head -6 /etc/passwd
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
[root@Linux100 tmp]# head -6 /etc/passwd | cat -n 
     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
     6    sync:x:5:0:sync:/sbin:/bin/sync
[root@Linux100 tmp]# head -6 /etc/passwd | cat -n | tac
     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  set -n '1h;G;x;$p' 
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed -n '1h;G;x;$p' 
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash
     1    root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed -n '1h;1!G;x;$p' 
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed -n '1h;1!G;$!x;$p' 
     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# 
[root@Linux100 tmp]# 
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed 'G;h'
     1    root:x:0:0:root:/root:/bin/bash

     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed 'G;h$p'
sed:-e 表达式 #1,字符 4:命令后含有多余的字符
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed 'G;h;$p'
     1    root:x:0:0:root:/root:/bin/bash

     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed -n  'G;h;$p'
     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed -n  '1!G;h;$p'
     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash
[root@Linux100 tmp]# cat -n /etc/passwd | head -6 |  sed  '1!G;h;$!d'
     6    sync:x:5:0:sync:/sbin:/bin/sync
     5    lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     4    adm:x:3:4:adm:/var/adm:/sbin/nologin
     3    daemon:x:2:2:daemon:/sbin:/sbin/nologin
     2    bin:x:1:1:bin:/bin:/sbin/nologin
     1    root:x:0:0:root:/root:/bin/bash

AWK  

AWK和 sed的区别

  • awk更像是脚本语言;
  • awk用于“比较规范”的文本处理,用于统计数量并输出指定字段;
  • 使用sed将不规范的文本,处理为“比较规范”的文本;

AWK脚本的流程控制

  • 输入数据前例程 BEGIN{ } 
  • 主输入循环 { }
  • 所有文件读取完成例程 END { } 

 记录和字段

  • 每行称作AWK的记录;
  • 使用空格、制表符分隔开的单词称作字段;
  • 可以自己指定分割的字段;

字段的引用

awk中使用$1  $2... $n 表示每一个字段;

  • awk '{print $1, $2, $3}'  filename 

awk可以使用 -F 选项改变字段分隔符

  • awk -F ',' '{print $1, $2, $3}' filename
  • 分隔符可以使用正则表达式
[root@Linux100 ~]# awk -F "'"  '/^menu/{ print $2 }' /boot/grub2/grub.cfg 
CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)
CentOS Linux (0-rescue-664dbe28ab4f4a9eb3041dd0dc965aed) 7 (Core)
[root@Linux100 ~]# 
[root@Linux100 ~]# awk -F "'"  '/^menu/{ print x++,$2 }' /boot/grub2/grub.cfg 
0 CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)
1 CentOS Linux (0-rescue-664dbe28ab4f4a9eb3041dd0dc965aed) 7 (Core)

AWK的表达式

① 赋值操作符

= 是最常用的赋值操作符

  • var1 = "name"
  • var2 = "hello" "world"
  • var3 = $1   (表示分割开的第一个字段)

其他赋值操作符

  • ++  --  +=  -=  *=  /=  %=  ^= 

② 算数操作符

  • +  -  *  /  %  ^  

③ 系统变量

  • FS和OFS字段分隔符,OFS表示输出的字段分隔符,FS输入
  • RS记录分隔符 
  • NR和FNR行数  
  • NF字段数量,最后一个字段内容可以用$NF 取出 

④ 关系操作符

  •  <  >  <=  >=  ==  !=  ~  !~  

⑤ 布尔操作符

  • &&   ||    !
[root@Linux100 ~]# head -5 /etc/passwd
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
[root@Linux100 ~]# 
[root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":"} {print $1}'
root
bin
daemon
adm
lp
[root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":"} {print $1,$2}'
root x
bin x
daemon x
adm x
lp x
[root@Linux100 ~]# head -5 /etc/passwd | awk -F ":" 'BEGIN{FS=":";OFS="-"} {print $1,$2}'
root-x
bin-x
daemon-x
adm-x
lp-x
[root@Linux100 ~]# 
[root@Linux100 ~]# head -5 /etc/passwd
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
[root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{RS=":"} {print $0}'
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

[root@Linux100 ~]# head -5 /etc/passwd | awk '{print NR}'
1
2
3
4
5
[root@Linux100 ~]# head -5 /etc/passwd | awk '{print NR,$0}'
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@Linux100 ~]# head -5 /etc/passwd | awk '{print NFR,$0}'
 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
[root@Linux100 ~]# 
[root@Linux100 ~]# 
[root@Linux100 ~]# 
[root@Linux100 ~]#  awk '{print NFR,$0}' /etc/hosts /etc/hosts
hosts        hosts.allow  hosts.deny   
[root@Linux100 ~]#  awk '{print NFR,$0}' /etc/hosts /etc/hosts 
 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
 192.168.10.100 Linux100
 192.168.10.101 Linux101
 192.168.10.102 Linux102
 192.168.10.103 Linux103
 192.168.10.104 Linux104
 
 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
 192.168.10.100 Linux100
 192.168.10.101 Linux101
 192.168.10.102 Linux102
 192.168.10.103 Linux103
 192.168.10.104 Linux104
 
[root@Linux100 ~]#  awk '{print NR,$0}' /etc/hosts /etc/hosts 
1 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
2 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
3 192.168.10.100 Linux100
4 192.168.10.101 Linux101
5 192.168.10.102 Linux102
6 192.168.10.103 Linux103
7 192.168.10.104 Linux104
8 
9 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
10 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
11 192.168.10.100 Linux100
12 192.168.10.101 Linux101
13 192.168.10.102 Linux102
14 192.168.10.103 Linux103
15 192.168.10.104 Linux104
16 
[root@Linux100 ~]# 
[root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{FS=":"} {print NF}'
7
7
7
7
7
[root@Linux100 ~]# head -5 /etc/passwd | awk 'BEGIN{FS=":"} {print $NF}'
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin

 

AWK判断和循环

AWK的条件和循环 

① 条件语句

  • 条件语句使用if开头,根据表达式的结果来判断执行哪条语句

    if (表达式) 

        awk语句1 

    [

        awk语句2 

    ]

  • 如果有多个语句需要执行可以使用{ } 将多个语句括起来

② 循环

① while 循环

  while(表达式)

    awk语句1 

② do循环

  do{

    awk语句1

  }while(表达式)

③ for循环

  for( 初始值; 循环判断条件; 累加 )

    awk语句1

④ 影响控制的其他语句

  • break
  • continue
[root@Linux100 ~]# cat  kpi.txt
user1 70 72 74 76 74 72
user2 80 82 84 84 80 78
user3 60 61 62 63 64 65
user4 90 89 88 87 86 85
user5 45 60 63 62 61 50
[root@Linux100 ~]# awk '{if($2>=80) print $1}' kpi.txt 
user2
user4
[root@Linux100 ~]# awk '{if($2>=80) { print $1 ; print $2 } }' kpi.txt 
user2
80
user4
90
[root@Linux100 ~]# 
[root@Linux100 ~]# cat kpi.txt 
user1 70 72 74 76 74 72
user2 80 82 84 84 80 78
user3 60 61 62 63 64 65
user4 90 89 88 87 86 85
user5 45 60 63 62 61 50
[root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) print c}'
2
3
4
5
6
7
[root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) print $c}'
70
72
74
76
74
72
[root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum}'
438
[root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/6}'
73
[root@Linux100 ~]# head -1 kpi.txt | awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}'
73
[root@Linux100 ~]# awk '{for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}' kpi.txt 
73
154.333
216.833
304.333
361.167
[root@Linux100 ~]# cat kpi.txt 
user1 70 72 74 76 74 72
user2 80 82 84 84 80 78
user3 60 61 62 63 64 65
user4 90 89 88 87 86 85
user5 45 60 63 62 61 50
[root@Linux100 ~]# awk '{sum=0; for(c=2;c<=NF;c++) sum+=$c ; print sum/(NF-1)}' kpi.txt 
73
81.3333
62.5
87.5
56.8333

awk数组

① 数组的定义

数组:一组有某种关联的数据(变量),通过下标依次访问;

  • 数组名[下标] = 值
  • 下标可以使用数字也可以使用字符串

 

② 数组的遍历

for (变量  in  数组名) 

  • 使用数组名[变量] 的方式依次对每个数组的元素进行操作

③ 删除数组

  • delete 数组[下标] 

④ 命令行参数数组

  • ARGC
  • ARGV
[root@Linux100 ~]# cat kpi.txt 
user1 70 72 74 76 74 72
user2 80 82 84 84 80 78
user3 60 61 62 63 64 65
user4 90 89 88 87 86 85
user5 45 60 63 62 61 50
[root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) print user,average[user]}' kpi.txt 
user1 73
user2 81.3333
user3 62.5
user4 87.5
user5 56.8333
[root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) sum2+=average[user] ;  print sum2/NR }' kpi.txt 
72.2333
[root@Linux100 ~]# awk '{ sum=0; for(column=2;column<=NF;column++) sum+=$column; average[$1]=sum/(NF-1)} END{ for( user in average) sum2+=average[user] ;  print sum2}' kpi.txt 
361.167
[root@Linux100 ~]# 

[root@Linux100 ~]# vim avg.awk
BEGIN{
        for(x=0;x<ARGC;x++)
                print ARGV[x]
                print ARGC
}

[root@Linux100 ~]# awk -f  avg.awk 11 22 33
awk
11
22
33
4

awk数组功能的使用

[root@Linux100 ~]# vim result.awk
{
sum = 0
for( column = 2; column <= NF; column++ )
      sum += $column
average[$1] = sum / ( NF - 1)

if( average[$1] >= 80 )
    letter = "S"
else if( average[$1] >= 70 )
    letter = "A"
else if( average[$1] >= 60 )
    letter = "B"
else 
    letter = "C"

print $1,average[$1],letter

letter_all[letter]++

}
END {

for( user in average )
     sum_all += average[user]
avg_all = sum_all / NR

print "average all:",avg_all

for( user in average )
    if( average[user] > avg_all )
        above++
    else 
        below++
print "above",above
print "below",below
print "S",letter_all["S"]
print "A",letter_all["A"]
print "B",letter_all["B"]
print "C",letter_all["C"]

}

[root@Linux100 ~]# awk -f result.awk kpi.txt 
user1 73 A
user2 81.3333 S
user3 62.5 B
user4 87.5 S
user5 56.8333 C
average all: 72.2333
above 3
below 2
S 2
A 1
B 1
C 1

 AWK的函数

① 算数函数

  • sin()  cos()
  • int()
  • rand()  srand()

② 字符串函数

  • gsub(r,s,t)
  • index(s,t)
  • length(s)
  • match(s, r)
  • split(s, q, seq)
  • sub(r, s, t)
  • substr(s, p, n)

 

③ 自定义函数

  function 函数名(参数) {

    awk语句

    return awk变量

  }

[root@Linux100 ~]# awk 'BEGIN{pi=3.14 ;print int(pi)}'
3
[root@Linux100 ~]# awk 'BEGIN{pi=3.14 rand()}'
[root@Linux100 ~]# awk 'BEGIN{print rand()}'
0.237788
[root@Linux100 ~]# awk 'BEGIN{print rand()}'
0.237788
[root@Linux100 ~]# awk 'BEGIN{print rand()}'
0.237788
[root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}'
0.823533
[root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}'
0.679848
[root@Linux100 ~]# awk 'BEGIN{srand(); print rand()}'
0.105157
[root@Linux100 ~]# 
[root@Linux100 ~]# 
[root@Linux100 ~]# 
[root@Linux100 ~]# awk 'function a(){ return 0} BEGIN{ print a() }'
0
[root@Linux100 ~]# awk 'function double(str) {return str str }  BEGIN{ print double("hello awk") }'
hello awkhello awk

 

2. shell工具 

cut

cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的。cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。

-f (列号,提取第几列)   -d(分隔符,按照指定分隔符分割列)    -c   (指定具体字符,如5--9个字符)


[root@kris datas]# ifconfig | grep Bcast 
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
[root@kris datas]# ifconfig | grep Bcast | cut -c 11-14
inet

[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2
192.168.1.100  Bcast
[root@kris ~]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 1 
192.168.1.100
[root@kris datas]# ifconfig | grep Bcast > temp.log  ##### > 是把原来的内容覆盖、>>是在原内容基础上追加; 
[root@kris datas]# cat temp.log 
          inet addr:192.168.1.100  Bcast:192.168.1.255  Mask:255.255.255.0
[root@kris datas]# cut -d : -f 2 temp.log          
192.168.1.100  Bcast
[root@kris datas]# cat temp.log | cut -d : -f 2  #####与上边是的等效的,只是temp.log所放的位置不一样
192.168.1.100  Bcast
[root@kris datas]# ifconfig | grep Bcast | cut -d : -f 2 | cut -d " " -f 3
Bcast

 

 sed

sed按行处理;

sed是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出

 -e(直接在指令列模式上进行sed的动作编辑;两个修改指令的方式)  -i (在文件中直接编辑修改文件)   

a(新增,a的后面可以接字串,在下一行出现 '2axxxx' )  d (删除)

 s(查找并替换 ‘s/Link/xxxx/’ 

ifconfig | sed '1d'    删除第一行

 ifconfig | sed '1,5d' 删除掉前5行

 ifconfig | sed '1akris'  在第一行后面(第二行)追加kris

ifconfig | sed 's/Link/XXX/' 查找并替换;注意是区分大小写的,最后的/符号不要忘记了ifconfig | sed 's/Link/XXX/' temp.log  #并不会改变文件内容

 ifconfig | sed -i 's/Link/XXX/' temp.log  加上-i就可以在文件中修改成功了;前提是文件中的内容必须是ifconfig输出内容;
ifconfig | sed  '/^ *R/aXXX'  前边有若干个空格,以R开头的

[root@kris datas]# ifconfig | sed -e '/^ *R/aXXX' -e'/^ *T/d'   
以R开头的追加XXX
,把以T开头的删掉;这是两个式子就不能通过一个式子搞定了,需加-e改变修改方式只有一个时可以省略;

 

 awk

一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

按行处理,可以对行内的数据进行更细微的操作;

awk [选项参数] ‘pattern1{action1}  pattern2{action2}...’ filename

  pattern:表示AWK在数据中查找的内容,就是匹配模式

  action:在找到匹配内容时所执行的一系列命令

  选项参数:-F(指定输入文件折分隔符)、-v(赋值一个用户定义变量)

cp /etc/passwd ./
[root@kris datas]# cat passwd | awk '/^a/{print}' 把以a开头的打印出来 [root@kris datas]# cat passwd | awk '/^a/{print}'   adm:x:3:4:adm:/var/adm:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin [root@kris datas]# cat passwd | awk -F : '/^a/{print $1}' //-F指定输入文件折分隔符   adm   avahi-autoipd   abrt   apache [root@kris datas]# cat passwd | awk -F: '/^a/{print $1} /^adm/{print}' 如果匹配到了以a开头就把print $1打印出来; 如果又匹配到了adm就把print整行打印出;

  adm
  adm:x:3:4:adm:/var/adm:/sbin/nologin
  avahi-autoipd
  abrt
  apache
  alex

#如果不写模板它就把所有行都打印出
[root@kris datas]# cat passwd | awk -F : '{print $1}'   ...... [root@kris datas]#
cat passwd | awk -F: 'BEGIN{print "begin"} {print$1} END{print "end"}'
  #begin在数据输入之前先执行BEGIN这个块里边的;END是所有数据处理完了再执行这个块里边的东西;
  begin
  ...
  end

 [kris@hadoop datas]$ cat passwd
  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:sh.....

[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3} END{print "Sum="sum}'  #把第3列的数值加到sum上,对文件的第3列做累加;
  Sum=0
  Sum=3222
[root@kris datas]# cat passwd | awk -F: 'BEGIN{sum=0;print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}' ###上面求和的过程


[root@kris datas]# which awk
/bin/awk
[root@kris datas]# ll /bin/awk
lrwxrwxrwx. 1 root root 4 9月   3 2013 /bin/awk -> gawk  
[root@kris datas]# cat passwd | awk -F: -v sum=0 'BEGIN{print "Sum="sum} {sum+=$3; print $3"Sum="sum} END{print "Sum="sum}'  #-v就是引入一个变量


awk的内置变量
[root@kris datas]# cat temp | awk 'BEGIN{sum=0}{sum+=1}/^$/{print sum}'  #打印出文件的所有空行的行号,下面这种方法更简单;

[root@kris datas]# cat temp | awk '/^$/{print NR}' #NR就起到sum的作用; 也可这样写: awk '/^$/{print NR}' temp
2
3
5
7
8
10
11
12

[root@kris datas]# awk '/^$/{print FILENAME}' temp  ##每列输出文件名
temp
temp
temp


[root@kris datas]# awk -F : '{print NF}' passwd   #######NF是按:切割的列数,一共多少列;  
7
7
7
...

[root@kris datas]# awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:"NF}' passwd 
filename:passwd, linenumber:1,columns:7
filename:passwd, linenumber:2,columns:7
filename:passwd, linenumber:3,columns:7
[root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}'
192.168.1.100  Bcast
[root@kris datas]# ifconfig  eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
192.168.1.100

 

一个目录下(包括子目录)一共有多少个java文件? 如何取得每一个文件的名称? 
[kris@hadoop ~]$ sudo find / -name "*.java"
/root/anaconda3/pkgs/spyder-3.3.2-py37_0/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
/root/anaconda3/lib/python3.7/site-packages/spyder/utils/tests/data/example.java
[kris@hadoop ~]$ sudo find / -name "*.java" | awk -F "/" '{print $NF}'  以/切割,NF这行一共有多少列,如一共8列,$NF表取第8列
example.java
example.java

 [kris@hadoop ~]$ basename /opt/module/hive
  hive

 

 

practice

使用Linux命令查询file1中空行所在的行号
[krs@hadoop101 datas]$ awk '/^$/{print NR}' file1.txt 
5
1.有文件chengji.txt内容如下:
张三 40
李四 50
王五 60

使用Linux命令计算第二列的和并输出
[kris@hadoop datas]$ cat chengji.txt | awk -F " " '{sum+=$2} END{print sum}'   ######### -F " " $2 分割的列不是从0开始数的,从1开始
150

2.用shell写一个脚本,对文本中无序的一列数字排序
[kris@hadoop datas]$ sort -n text.txt 
1
2
3
4
5
6
7
8
9
10

[kris@hadoop datas]$ sort -n text.txt | awk '{sum+=$0; print $0} END{print "sum="sum}'

  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  sum=55

3 用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容中包含有字符”kris”的文件名称
  [kris@hadoop datas]$ grep -r "kris" /home/ | cut -d : -f 1

 

sort

-n(依照数值的大小排序) 、  -r (以相反的顺序来排序) 、 -t (设置排序时所用的分隔字符) 、 -k(指定需要排序的列)

[root@kris datas]# cat passwd | grep ^a | sort -t : -k 3
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
apache:x:48:48:Apache:/var/www:/sbin/nologin
[root@kris datas]#
cat passwd | grep ^a | sort -t : -k 3 -n   adm:x:3:4:adm:/var/adm:/sbin/nologin   apache:x:48:48:Apache:/var/www:/sbin/nologin   avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin   abrt:x:173:173::/etc/abrt:/sbin/nologin
[root@kris datas]#
cat passwd | grep ^a | sort -t : -k 3 -nr abrt:x:173:173::/etc/abrt:/sbin/nologin avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin apache:x:48:48:Apache:/var/www:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin [root@kris datas]# sort -t : -nrk 3 sort.sh bb:40:5.4 bd:20:4.2 cls:10:3.5 xz:50:2.3 ss:30:1.6
posted @ 2019-01-17 18:03  kris12  阅读(288)  评论(0编辑  收藏  举报
levels of contents