目录
一.awk命令
1.0 man awk
[root@awk ~]# man awk
gawk - pattern scanning and processing language
Gawk - 模式扫描和处理语言
Gawk is the GNU Project's implementation of the AWK programming language. It conforms to the definition of the language in the POSIX 1003.1 Standard. This version in turn is based on the description in The AWK Programming Language, by Aho, Kernighan, Weinberger. Gawk provides the additional features found in the current version of UNIX awk and a number of GNU-specific extensions.
1.1 awk的工作原理
awk 是每次从文本中读取一行,按照指定的输入分隔符(默认分隔符为空格)进行切片,切成多个字段,将每片直接保存在内建的变量中,通过$1,$2,$3等来引用输出到屏幕。
1.2 awk的基本用法格式
awk 'BEGIN{commands}pattern{commands}END{commands}' file
首先执行BEGIN{commands}语句块中的语句 从文件中读取第1行, 如果有pattern则进行模式匹配, 若无pattern则执行{}中的语句,接着读取下一行,重复这个过程, 直到所有的行被读取完毕,最后执行END{commands}语句块中的语句。
1.3 awk命令的内部变量
内置变量:awk 自带的变量,不需要定义
NR:number of record 记录的编号,一行就是一条记录
NF:number of field 字段数,一行有多少列FS 当前的输入分割符,默认是空白字符(空格和tab)
field separator
OFS 当前的输出分割符,默认是空格字符(空格)
output field separator
1.4 指定分割符
-F 指定分割符
OFS 定义输出分隔符
[root@awk 7-1]# cat grade.txt
name chinese math English
cali 80 91 82
tom 90 80 99
lucy 99 70 75
jack 60 89 99
[root@awk 7-1]# cat grade.txt |awk '{print $1,$2}'
name chinese
cali 80
tom 90
lucy 99
jack 60
[root@awk ~]# awk -F: '/bin/bash{print $1}' /etc/passwd
root
bin
daemon
adm
[root@ansible_nfs 7-1]# df |awk 'OFS="#"{print NR,$(NF-1)}'
1#已用%
2#0%
3#0%
4#2%
5#0%
6#36%
7#19%
8#0%
1.5 awk的示例
[root@ansible_nfs 7-1]# who
root pts/0 2023-07-03 19:24 (192.168.102.1)
root pts/2 2023-07-03 19:24 (192.168.102.1)
[root@ansible_nfs 7-1]# who |awk '{print $2}'
pts/0
pts/2
[root@ansible_nfs 7-1]# awk -F: '/^h/{print $1}' /etc/passwd
halt
[root@ansible_nfs 7-1]# cat /etc/passwd|tail
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
[root@ansible_nfs 7-1]# awk -F[:/] '{print $1,$10}' /etc/passwd
rpc
[root@ansible_nfs 7-1]# awk -F[:/] '{print $1,$9}' /etc/passwd
rpc rpcbind
1.6 awk命令的操作符
正则表达式和bash一致
数学运算:+,-,*,/, %,++,- -
逻辑关系符:&&, ||, !
&& 比||的优先级要高
比较操作符:>,<,>=,!=,<=,== ~ !~
文本数据表达式:== (精确匹配)
~波浪号表示匹配后面的模式(模糊匹配)
示例
[root@ansible_nfs 7-1]# awk -F: '$1 == "git"{print $1,$7}' /etc/passwd
git /bin/sh
[root@ansible_nfs 7-1]# awk -F: '$1 ~ "git"{print $1,$7}' /etc/passwd
gitlab-www /bin/false
git /bin/sh
gitlab-redis /bin/false
gitlab-psql /bin/sh
gitlab-prometheus /bin/sh
[root@ansible_nfs 7-1]# awk -F: '$1 !~ "git"{print $1,$7}' /etc/passwd
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
[root@ansible_nfs 7-1]# awk -F: '$1 ~ /\<...\>/ {print $1,$3}' /etc/passwd
bin 1
adm 3
ftp 14
rpc 32
gitlab-www 996
git 995
liu 1001
[root@ansible_nfs 7-1]# awk -F: 'length($1) == 3 {print $1,$3}' /etc/passwd
bin 1
adm 3
ftp 14
rpc 32
git 995
liu 1001
[root@ansible_nfs 7-1]# seq 100 |awk '$1 % 5 == 0 && $1 ~ /^1/{print $1}'
10
15
100
1.7 shell 里的变量传递到 awk 内部
1. -v 选项
[root@ansible_nfs ~]# name=haha
[root@ansible_nfs ~]# echo |awk '{print $name}'
[root@ansible_nfs ~]# echo $name|awk '{print $name}'
haha
[root@ansible_nfs ~]# echo|awk -v abc=$name '{print abc}'
haha
2.使用双引号,$符号需要转义\
[root@ansible_nfs ~]# awk -F: "\$1 ~ /$name/{print \$1,\$3}" /etc/passwd
root 0
1.8 awk的if单分支和多分支
单分支
if (condition) statement1
awk -F: '$1~/^...$/' /etc/passwd awk -F: '{if($3 >= 500)print $1,$7}' /etc/passwd
if (condition) statement1 ; else statement2
awk -F: '{if($3 != 0) print $1 ; else print $3}' /etc/passwd
多分支
awk -F: '{if($1=="root") print $1; else if($1=="ftp") print $2; else if($1=="mail") print $3; else print NR}' /etc/passwd
if (表达式 ) {
语句;语句;... }
else if (表达式 ) {
语句;语句;... }
else if (表达式 ) {
语句;语句;... }
else { 语句;语句;...
}
awk {
if ( $3 > 89 && $3 < 101 ) Agrade ++
else if ( $3 > 79 ) Bgrade ++
else if ( $3 > 69 ) Cgrade ++
else if ( $3 > 59 ) Dgrade ++
else Fgrade ++
}END {
print "The number of failures is "Fgrade
} filename
1.9 awk进行列求和
1. 统计/etc目录下以.conf结尾的文件的总大小
[root@awk 7-1]# find /etc/ -type f -name "*.conf" |xargs ls -l | awk '{sum+=$5} END{print sum}'
248796
2. awk进行行求和
[root@awk 7-1]# echo 1 2 3 4 5 | awk '{for(i=1;i<=NF;i++) sum+=$i; print sum}'
15
[root@awk 7-1]# seq -s ' ' 100 | awk '{for(i=1;i<=NF;i++) sum+=$i; print sum}'
5050
3. awk的其他用法探索
[root@ansible_nfs ~]# a=1.4
[root@ansible_nfs ~]# b=5.8
[root@ansible_nfs ~]# echo |awk "{print $a + $b}"
7.2
二. cut 命令
cut - remove sections from each line of files
从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段输出。
截取字符串和列
1.截取字符串
-c 指定字符串的长度
-b 以字节为单位进行分割
2.截取列
-f 指定字段数
-d 指定分隔符
默认的分隔符是TAB
awk的默认分隔符是空白(TAB和空格)
[root@aliyun shell]# echo "我爱你中国" | cut -c 2,3
爱你
[root@aliyun shell]# echo "我爱你中国" | cut -b 2,3
#新建20个用户
[root@aliyun shell]# useradd sc{1..20}
# 给这20个用户设置10位长度的字符
[root@aliyun shell]# echo 12345|md5sum|cut -b -10|passwd sc{1..20} --stdin
d577273ff8
[root@ansible_nfs 7-1]# df
文件系统 1K-块 已用 可用 已用% 挂载点
devtmpfs 919460 0 919460 0% /dev
tmpfs 931408 0 931408 0% /dev/shm
tmpfs 931408 9736 921672 2% /run
tmpfs 931408 0 931408 0% /sys/fs/cgroup
/dev/mapper/centos-root 17811456 6302264 11509192 36% /
/dev/sda1 1038336 194028 844308 19% /boot
tmpfs 186284 0 186284 0% /run/user/0
[root@ansible_nfs 7-1]# df |cut -d " " -f 1,3
文件系统
devtmpfs
tmpfs
tmpfs
tmpfs