[命令] Linux 命令 sed (修改和打印文本的行)

内容目录:

内容一:sed 格式

内容二:sed 选项

内容三:sed 的参数

内容四:sed 的使用案例
4.1 案例一:使用 p 参数打印某一行数据
4.1.1 在 test.txt 文本里打印第二行的数据
4.1.2 在 test.txt 文本里打印第二行到第四行的数据
4.1.3 在 test.txt 文本里打印最后一行的数据
4.1.4 在 test.txt 文本里打印包含 eternalcenter 的数据
4.1.5 在 test.txt 文本里打印以 eternalcenter 结尾的数据
4.1.6 在 test.txt 文本里输出总行数
4.1.7 在 test.txt 文本里输出奇数行
4.1.8 在 test.txt 文本里输出偶数行
4.2 案例二:使用 a 参数在某一行下面追加一行数据
4.2.1 在 test.txt 文本里在第二行下面追加一行 eternalcenter
4.2.2 在 test.txt 文本里在 abc 那一行下面添加一行 eternalcenter
4.2.3 在 test.txt 文本里在以 a 开头的行下面添加 eternalcenter
4.2.4 在 test.txt 文本里在以 [a] 开头的行下面添加 eternalcenter
4.2.5 在 test.txt 文本里最后一行下面添加 eternalcenter
4.3 案例三:使用 i 参数在某一行上面插入一行数据
4.3.1 在 test.txt 文本里在第二行上面插入一行 eternalcenter
4.3.2 在 test.txt 文本里在 abc 那一行上面添加一行 eternalcenter
4.3.3 在 test.txt 文本里在以 a 开头的行上面添加 eternalcenter
4.3.4 在 test.txt 文本里在以 [a] 开头的行上面添加 eternalcenter
4.3.5 在 test.txt 文本里最后一行上面添加 eternalcenter
4.4 案例四:使用 c 参数替换某一行数据
4.4.1 在 test.txt 文本里将第二行替换成 eternalcenter
4.4.2 在 test.txt 文本里将 abc 那一行替换成 eternalcenter
4.4.3 在 test.txt 文本里将以 a 开头的那一行替换成 eternalcenter
4.4.4 在 test.txt 文本里将以 [a] 开头的那一行替换成 eternalcenter
4.4.5 在 test.txt 文本里将以 eternalcentre 开头的那一行替换成 eternalcenter ALL=(ALL) NOPASSWD: ALL
4.5 案例五:使用 d 参数删除某一行
4.5.1 在 test.txt 文本里删除第二行
4.5.2 在 test.txt 文本里删除包含 abc 的那一行
4.5.3 在 test.txt 文本里删除以 a 开头的那一行
4.5.4 在 test.txt 文本里删除以 [a] 开头的那一行
4.5.5 在 test.txt 文本里删除第二行到第四行
4.6 案例六:使用 s 参数替换某一行某些数据
4.6.1 在 test.txt 文本里将所有行的第一个 eternalcentre 换成 eternalcenter
4.6.2 在 test.txt 文本里将所有行的所有 eternalcentre 换成 eternalcenter
4.6.3 在 test.txt 文本里将包含 eternalcentre 的行换成 eternalcenter
4.6.4 在 test.txt 文本里将第三行的第二个 eternalcentre 换成 eternalcenter
4.6.5 在 test.txt 文本里在所有行前面添加 eternalcenter
4.6.6 在 test.txt 文本里将第二行替换成 eternalcenter
4.6.7 在 test.txt 文本里将最后一行替换成 eternalcenter
4.6.8 在 test.txt 文中里将第二到第三行替换成 eternalcenter
4.6.9 在 test.txt 文本里将 eternalcenter 前面的数据和后面的数据对调位置
4.6.10 在 test.txt 文本里删除每行的第一个字符和最后一个字符
4.6.11 在 test.txt 文本里删除每行的第二个字符和最后一个字符
4.6.12 在 test.txt 文本里删除所有的数字和空格
4.6.13 在 test.txt 文本里将所有的大写字母都添加括号
4.6.14 在 test.txt 文本里给第七行和第九行前面添加 “#”
4.6.15 在 test.txt 文本里删除第一个空格
4.7 案例七:使用 h、H、g、G 参数复制和粘贴
4.7.1 sed 命令的工作原理
4.7.2 h、H、g、G、d、D 参数的讲解
4.7.2.1 h、H、g、G、d、D 参数的作用简介
4.7.2.2 h、H、g、G、d、D 的功能示意图
4.7.3 h、H、g、G、d、D 的使用案例
4.7.3.1 将第一行的数据添加到第三行后面
4.7.3.2 将第一行的数据替换第三行
4.7.3.3 将第一行和第二行的数据添加到第三行后面
4.7.3.4 将第一行和第二行的数据替换第三行
4.7.3.5 将第一个以 a 开头的行的数据添加到第三行后面
4.7.3.6 将第一个和第二个以 a 开头的行的数据添加到第三行后面
4.8 案例八:sed 一次匹配多个参数

具体的内容:

内容一:sed 格式

# sed <option> <parameter> <file>

内容二:sed 选项

1) -n 或 –quiet 或 –silent 仅显示处理后的内容,没处理的内容就不显示了
2) -i 实现数据的变更
3) -e <脚本> 或 –expression=<脚本> 以指定的脚本来处理输入的文本
4) -r 支持扩展正则
5) -f <脚本文件> 或 –file=<脚本文件> 以指定的脚本文件来处理输入的文本
6) -h 或 –help 显示帮助内容
7) -V 或 –version 显示版本信息

内容三:sed 的参数

1) p 打印某一行的数据
2) a 在某一行下面追加一行的数据
3) i 在某一行上面插入一行的数据
4) c 替换某一行的数据
5) d 删除某一行
6) s 替换某一行的某些数据
7) h、H、g、G 复制和粘贴某些行的数据

内容四:sed 的使用案例
4.1 案例一:使用 p 参数打印某一行数据
4.1.1 在 test.txt 文本里打印第二行的数据

# sed -n 2p test.txt

4.1.2 在 test.txt 文本里打印第二行到第四行的数据

# sed -n 2,4p test.txt

4.1.3 在 test.txt 文本里打印最后一行的数据

# sed -n '$p' test.txt

4.1.4 在 test.txt 文本里打印包含 eternalcenter 的数据

# sed -n '/eternalcenter/p' test.txt

4.1.5 在 test.txt 文本里打印以 eternalcenter 结尾的数据

# sed -n '/eternalcenter$/p' test.txt

4.1.6 在 test.txt 文本里输出总行数

# sed -n $= test.txt

4.1.7 在 test.txt 文本里输出奇数行

# sed -n 'p;n' test.txt

4.1.8 在 test.txt 文本里输出偶数行

# sed -n 'n;p' test.txt

4.2 案例二:使用 a 参数在某一行下面追加一行数据
4.2.1 在 test.txt 文本里在第二行下面追加一行 eternalcenter

# sed "2a eternalcenter" test.txt

4.2.2 在 test.txt 文本里在 abc 那一行下面添加一行 eternalcenter

# sed "/abc/a eternalcenter" test.txt

4.2.3 在 test.txt 文本里在以 a 开头的行下面添加 eternalcenter

# sed "/^a/a eternalcenter" test.txt

4.2.4 在 test.txt 文本里在以 [a] 开头的行下面添加 eternalcenter

# sed "/^\[a\]/a eternalcenter" test.txt

4.2.5 在 test.txt 文本里最后一行下面添加 eternalcenter

# sed "$a eternalcenter" test.txt

4.3 案例三:使用 i 参数在某一行上面插入一行数据
4.3.1 在 test.txt 文本里在第二行上面插入一行 eternalcenter

# sed "2i eternalcenter" test.txt

4.3.2 在 test.txt 文本里在 abc 那一行上面添加一行 eternalcenter

# sed "/abc/i eternalcenter" test.txt

4.3.3 在 test.txt 文本里在以 a 开头的行上面添加 eternalcenter

# sed "/^a/i eternalcenter" test.txt

4.3.4 在 test.txt 文本里在以 [a] 开头的行上面添加 eternalcenter

# sed "/^\[a\]/i eternalcenter" test.txt

4.3.5 在 test.txt 文本里最后一行上面添加 eternalcenter

# sed "$a eternalcenter" test.txt

4.4 案例四:使用 c 参数替换某一行数据
4.4.1 在 test.txt 文本里将第二行替换成 eternalcenter

# sed "2c\ eternalcenter" test.txt

或者:

# sed "2ceternalcenter" test.txt

4.4.2 在 test.txt 文本里将 abc 那一行替换成 eternalcenter

# sed "/abc/c\ eternalcenter" test.txt

或者:

# sed "/abc/ceternalcenter" test.txt

4.4.3 在 test.txt 文本里将以 a 开头的那一行替换成 eternalcenter

# sed "/^a/c\ eternalcenter" test.txt

或者:

# sed "/^a/ceternalcenter" test.txt

4.4.4 在 test.txt 文本里将以 [a] 开头的那一行替换成 eternalcenter

# sed "/^\[a\]/c\ eternalcenter" test.txt

或者:

# sed "/^\[a\]/ceternalcenter" test.txt

4.4.5 在 test.txt 文本里将以 eternalcentre 开头的那一行替换成 eternalcenter ALL=(ALL) NOPASSWD: ALL

# sed "/^eternalcentre/c\ eternalcenter\ ALL=\(ALL\)\ NOPASSWD:\ ALL" test.txt

或者:

# sed "/^eternalcentre/c\eternalcenter\ ALL=\(ALL\)\ NOPASSWD:\ ALL" test.txt

4.5 案例五:使用 d 参数删除某一行
4.5.1 在 test.txt 文本里删除第二行

# sed 2d test.txt

4.5.2 在 test.txt 文本里删除包含 abc 的那一行

# sed /"abc"/d test.txt

4.5.3 在 test.txt 文本里删除以 a 开头的那一行

# sed /"^a"/d test.txt

4.5.4 在 test.txt 文本里删除以 [a] 开头的那一行

# sed /"^\[a\]"/d test.txt

4.5.5 在 test.txt 文本里删除第二行到第四行

# sed '2,4d' test.txt

4.6 案例六:使用 s 参数替换某一行某些数据
4.6.1 在 test.txt 文本里将所有行的第一个 eternalcentre 换成 eternalcenter

# sed 's/eternalcentre/eternalcneter/' test.txt

4.6.2 在 test.txt 文本里将所有行的所有 eternalcentre 换成 eternalcenter

# sed 's/eternalcentre/eternalcneter/g' test.txt

4.6.3 在 test.txt 文本里将包含 eternalcentre 的行换成 eternalcenter

# sed 's/.*eternalcentre.*/eternalcneter/' test.txt

4.6.4 在 test.txt 文本里将第三行的第二个 eternalcentre 换成 eternalcenter

# sed '3s/eternalcentre/eternalcenter/2' 1.txt

4.6.5 在 test.txt 文本里在所有行前面添加 eternalcenter

# sed 's/^/eternalcenter/g' test.txt

4.6.6 在 test.txt 文本里将第二行替换成 eternalcenter

# sed '2s/.*/eternalcenter/' test.txt

4.6.7 在 test.txt 文本里将最后一行替换成 eternalcenter

# sed '$s/.*/eternalcenter/' test.txt

4.6.8 在 test.txt 文中里将第二到第三行替换成 eternalcenter

# sed '2,3s/.*/eternalcenter/' test.txt

4.6.9 在 test.txt 文本里将 eternalcenter 前面的数据和后面的数据对调位置

# sed "s/^\(.*\)\(eternalcenter\)\(.*\)$/\3\2\1/" test.txt

或者:

# sed -r "s/(.*)(eternalcenter)(.*)/\3\2\1/" test.txt

4.6.10 在 test.txt 文本里删除每行的第一个字符和最后一个字符

# sed 's/.//1;s/.$//' test.txt

4.6.11 在 test.txt 文本里删除每行的第二个字符和最后一个字符

# sed 's/.//2;s/.$//' test.txt

4.6.12 在 test.txt 文本里删除所有的数字和空格

# sed -r 's/[0-9]//g;s/^( )+//' test.txt

4.6.13 在 test.txt 文本里将所有的大写字母都添加括号

# sed 's/[A-Z]/(&)/g' test.txt

4.6.14 在 test.txt 文本里给第七行和第九行前面添加 “#”

# sed '7,9s/^/#/' test.txt

4.6.15 在 test.txt 文本里删除第一个空格

# sed -r 's/( )(.*)/\2/'

4.7 案例七:使用 h、H、g、G 参数复制和粘贴
4.7.1 sed 命令的工作原理

1) 从第一行开始一行一行地读取文本里的内容
2) 每读取一行就将数据存入到 pattern space 里面
3) 在 pattern sapce 中执行 sed 命令
4) 再打印 pattern space 中的内容然后将其清空
5) 之后重复以上操作再开始读取文本里的下一行
6) pattern space 里的数据可以存储到 hold space 里面


补充:
pattern space 相当于处理数据的流水线
hold space 相当于暂时存储数据的仓库

4.7.2 h、H、g、G、d、D 参数的讲解
4.7.2.1 h、H、g、G、d、D 参数的作用简介

1) g 将 hold space 中的内容拷贝到 pattern space 中,原来 pattern space 里的内容清除
2) G 将 hold space 中的内容 append 到 pattern space\n 后
3) h 将 pattern space 中的内容拷贝到 hold space 中,原来的 hold space 里的内容被清除
4) H 将 pattern space 中的内容 append 到 hold space\n 后
5) d 删除 pattern 中的所有行,并读入下一新行到 pattern 中
6) D 删除 multiline pattern 中的第一行,不读入下一行

4.7.2.2 h、H、g、G、d、D 的功能示意图

P H     P H     P H
1    h  1 1  d    1

P H     P H     P H     P H
2 1  G  2 1  H  2 1  d    1
        1       1 2       2
                  1       1

P H     P H     P H
3 2  G  3 2  h  3 3
  1     2 1     2 2
        1       1 1

P H     P H
3 2  g  2 2
  1     1 1


注意:
1) 这里的 P 指的是 pattern space
2) 这里的 H 指的是 hold space


补充:
h 其实就是清空现在粘贴板里的内容然后重新复制
H 其实就是不清空现在粘贴板里的内容然后再再原来粘贴版的内容基础上再追加复制
g 其实就是替换粘贴
G 其实就是追加粘贴

4.7.3 h、H、g、G、d、D 的使用案例
4.7.3.1 将第一行的数据添加到第三行后面

# sed -e '1h' -e '3G' test.txt

4.7.3.2 将第一行的数据替换第三行

# sed -e '1h' -e '3g' test.txt

4.7.3.3 将第一行和第二行的数据添加到第三行后面

# sed -e '1h' -e '2H' -e '3G' test.txt

4.7.3.4 将第一行和第二行的数据替换第三行

# sed -e '1h' -e '2H' -e '3g' test.txt

4.7.3.5 将第一个以 a 开头的行的数据添加到第三行后面

# sed -e '/^a/h' -e '3G' 1.txt

4.7.3.6 将第一个和第二个以 a 开头的行的数据添加到第三行后面

# sed -e '/^a/h' -e'/^a/H' -e '3G' 1.txt

4.8 案例八:sed 一次匹配多个参数

分别在 test.txt 文本里在 abc 和 bbb 那两行下面添加一行 eternalcenter

# sed -e "/abc/a eternalcenter" -e "/^bbb/a eternalcenter" test.txt

[命令] Linux 命令 grep (打印文本的行)

案例一:grep 使用正则表达式匹配

# grep -E '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

或者:

# egrep '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例二:grep 显示行号
2.1 grep 显示某些关键字所在行行号

# egrep -n '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
16:IPADDR=192.168.8.31
18:GATEWAY=192.168.8.55

2.2 grep 显示哪些行号是空行

# egrep -n ^$ /etc/resolv.conf

案例三:grep 取反匹配
3.1 grep 取反不匹配某些关键字

# egrep -v '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens192
UUID=5cda4d03-45c9-4856-80a6-f0bd0962d871
DEVICE=ens192
ONBOOT=yes
NETMASK=255.255.255.0
ZONE=public

3.2 grep 取反不显示空行

# egrep -v ^$ /etc/resolve.conf
### /etc/resolv.conf is a symlink to /var/run/netconfig/resolv.conf
### autogenerated by netconfig!
#
# Before you change this file manually, consider to define the
# static DNS configuration using the following variables in the
# /etc/sysconfig/network/config file:
#     NETCONFIG_DNS_STATIC_SEARCHLIST
#     NETCONFIG_DNS_STATIC_SERVERS
#     NETCONFIG_DNS_FORWARDER
# or disable DNS configuration updates via netconfig by setting:
#     NETCONFIG_DNS_POLICY=''
#
# See also the netconfig(8) manual page and other documentation.
#
### Call "netconfig update -f" to force adjusting of /etc/resolv.conf.
nameserver 192.168.0.1

案例四:grep 完全匹配

# egrep -o '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
192.168.8.31
192.168.8.55

案例五:grep 匹配区分大小写

# egrep -i '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例六:grep 统计匹配成功次数

# egrep -c '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
2

案例七:grep 将匹配成功的部分自动添加颜色

# egrep --color=auto '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例八:grep 将匹配成功的部分自动取消颜色

# egrep --color=no '([1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}' /etc/sysconfig/network-scripts/ifcfg-ens192  
IPADDR=192.168.8.31
GATEWAY=192.168.8.55

案例九:grep 一次匹配多个参数

# grep -e root -e zhumingyu /etc/passwd
root:x:0:0:root:/root:/bin/bash
zhumingyu:x:1001:1001:root:/root:/bin/bash

[命令] Linux 命令 awk (打印文本的列)

内容目录:

内容一:awk 格式

内容二:选项
2.1 awk 的 -F 选项
2.2 awk 的 RS、ORS、FS、OFS 选项
2.3 awk 的 sub、gsub 选项
2.3.1 sub 和 gsub 的区别
2.3.2 sub 和 gsub 的格式
2.3.2.1 sub 的格式
2.3.2.2 gsub 的格式

内容三:awk 的常用内置变量

内容四: awk 的使用案例
4.1 案例一:awk 基础打印
4.1.1 打印文档第 1 列和第 3 列,但中间没有空格
4.1.2 打印文档第 1 列和第 3 列
4.1.3 打印文档第 1 列和第 3 列,但中间有很长的空格空间
4.1.4 打印倒数第 2 列
4.1.5 打印每一行的行号和列数
4.1.6 打印前一个命令结果的第 5 列
4.1.7 打印前一个命令结果的第 5 列
4.1.8 打印第 2 到最后 1 列
4.1.9 打印每行的行数、列数、第 1 列和最后 1 列,并且将冒号 “:” 视为分割符
4.1.10 打印第 1 列,这里的 \047 代表的是单引号 “’”,并且将冒号 “:” 视为分割符
4.2 案例二:awk 替换打印
4.2.1 将第 1 列为 root 的行的第 3 列替换成 “1” 后打印,并且将冒号 “:” 视为分割符
4.2.2 将全部横杠 “-” 替换成空值后打印
4.2.3 将全部横杠 “-” 替换成 3 个星号 “***” 后打印
4.2.4 给每一行前面添加行号后打印
4.2.5 以竖杠 “|” 作为分割符将第 2 列的数字去掉后打印
4.2.6 将句号 “.” 替换成换行符后打印
4.2.7 将换行符替换成句号 “.” 后打印
4.3 案例三:awk 变量
4.3.1 将 date 命令的运行结果,通过 getline 赋值给 d ,之后将 d 的值打印出来
4.3.2 将 eternalcenter 的值赋予给 content,并将 content 变量的值打印出来
4.4 案例四:awk 自定义分割列符号
4.4.1 将冒号 ”:“ 视为分割符
4.5 案例五:awk 打印常量
4.6 案例六:awk 使用正则表达式匹配
4.6.1 打印包含 Failed 的行的第 11 列
4.6.2 打印以 bash 结尾的行,并且将冒号 “:” 视为分割符
4.6.3 打印以 root 或者 adm 开头的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.6.4 打印以 r 或者 a 开头的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.6.5 打印第 1 列包含 root 的行,并且将冒号 “:” 视为分割符
4.6.6 打印第 7 列不以 nologin 结尾的行的第 1 列和第 7 列,并且将冒号 “:” 视为分割符
4.6.7 打印前一个命令包含 Rx p 的行的第 5 列
4.6.8 打印前一个命令以 / 结尾的行的第 4 列
4.6.9 打印第一列以两个数字结尾的行的第一列,并且将冒号 “:” 视为分割符
4.6.10 打印以 root 开头到以 mysql 开头的所有行的第 1 列,并且将冒号 “:” 视为分割符
4.7 案例七:awk 使用比较运算符匹配
4.7.1 打印行号等于 3 的行,并且将冒号 “:” 视为分割符
4.7.2 打印第 3 列数值等于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.7.3 打印第 3 列数值不等于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.7.4 打印第 3 列数值大于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.7.5 打印第 3 列数值小于 10 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符
4.7.6 打印第 3 列数值大于 10 并且小于 20 的行,并且将冒号 “:” 视为分割符
4.7.7 打印第 3 列数值大于 1000 或者小于 10 的行,并且将冒号 “:” 视为分割符
4.7.8 打印第 3 列乘以第 4 列小于 100 的行,并且将冒号 “:” 视为分割符
4.7.9 打印第 1 列为 root 的行,并且将冒号 “:” 视为分割符
4.8 案例八:awk 计算
4.8.1 0 + 1 = 1
4.8.2 x = 0 + 1
4.8.3 x = 8 + 2
4.8.4 x = 8 – 1
4.8.5 2 + 3 = 5
4.8.6 2 * 3 = 6
4.8.7 3.2 + 3.5 = 6.7
4.8.8 23 除 8 余 7
4.8.9 打印第 3 加上 10 的结果,并且将冒号 “:” 视为分割符
4.8.10 找 200 以内 3 的倍数
4.8.11 找 100 以内 7 的倍数或者包含 7 的数
4.8.12 将第 4 列求和后打印,并且将冒号 “:” 视为分割符
4.9 案例九:awk 计数
4.9.1 计算以 bash 结尾的行数
4.9.2 计算第 3 列小于等于 1000 的行数,并且将冒号 “:” 视为分割符
4.9.3 计算 3 列大于 1000 的行数,并且将冒号 “:” 视为分割符
4.9.4 计算第 7 列以 bash 结尾的行数,并且将冒号 “:” 视为分割符
4.9.5 计算第 3 列和第 4 列的和赋值给变量,将变量的值打印出来,并且将冒号 “:” 视为分割符
4.9.6 计算第 1 列所有值各自总共出现的次数
4.9.7 统计此行中横杠 “-” 出现的次数并将第 4 列替换为次数
4.10 案例十:awk if 判断语句计数
4.10.1 计算第 3 列小于等于 1000 的行数和第 3 列大于 1000 的行数,并且将冒号 “:” 视为分割符
4.10.2 计算第 7 列以 bash 结尾的行数和第 7 列不以 bash 结尾的行数,并且将冒号 “:” 视为分割符
4.10.3 如果第 3 列等于 0 则打印 “root”,否则打印 “not root”,并且将冒号 “:” 视为分割符
4.10.4 如果第 3 列大于 1000 则打印第 3 列的值,否则打印 “system id”,并且将冒号 “:” 视为分割符
4.11 案例十一:awk for 循环实现同时批量输出值的名称和值
4.11.1 创建数组 a,其中 a[0]=0 a[1]=11 a[2]=22,并且将数组 a 打印出来
4.11.2 统计所有的 IP 地址以及每一个 IP 地址访问的次数
4.11.3 统计所有的 IP 地址以及每一个 IP 地址访问的次数,并以从多到少的顺序进行排序
4.11.4 将每一列的值前面加上所属行的行号,按行打印出来
4.11.5 将每一列的值前面加上所属行的行号,按行打印出来
4.12 案例十二:awk 打印表格

具体的内容:

内容一:awk 格式

# awk <option> '<condition>{<command>}' <file>
# awk <option> ' BEGIN{<option> <command>} {<command>} END{<command>}' <file>


补充:在这里
BEGIN{ } 里的指令只执行 1 次,并且是最先执行
{ } 里的指令会一行行地执行文件里的内容
END{ } 里指令只执行 1 次,并且是最后执行

内容二:选项
2.1 awk 的 -F 选项

awk 默认是以空格分割列,但是也可以通 -F 参数指定分割每一列的符号

2.2 awk 的 RS、ORS、FS、OFS 选项

RS 全名为 Record Separator 即指定记录分隔符
ORS 全名为 Output Record Separate 即指定输出记录分隔符
FS 全名为 Field Separator 即指定字段分隔符
OFS 全名为 Output Field Separator 即指定输出字段分隔符

2.3 awk 的 sub、gsub 选项
2.3.1 sub 和 gsub 的区别

sub 只匹配第一个字符串,类似于 sed ‘s//’
gsub 匹配所有字符串,类似于 sed ‘s//g’

2.3.2 sub 和 gsub 的格式
2.3.2.1 sub 的格式

# sub (<original string or regular expression>, <substitution string>):
# sub (<original string or regular expression>, <substitution string>, <target string>)

2.3.2.2 gsub 的格式

# gsub (<original string or regular expression>, <substitution string>):
# gsub (<original string or regular expression>, <substitution string>, <target string>)

内容三:awk 的常用内置变量

1) $0 文本当前行的全部内容
2) $1 文本的第 1 列
3) $2 文本的第 2 列
4) $3 文本的第 3 列

(补充:“$” 号后面的数字以此类推)

5) NR 文本当前行的行数,也就是目前处于第几行
6) NF 文本当前行的列数,也就是目前一共有几列
7) $(NF-1) 文本倒数第一列
8) $(NF-2) 文本倒数第二列
9) $(NF-3) 文本倒数第三列
10) , 代表空格
11) \t 代表 tab 制表位,就是比一个空格更多的空格

内容四: awk 的使用案例
4.1 案例一:awk 基础打印
4.1.1 打印文档第 1 列和第 3 列,但中间没有空格

# awk '{print $1,$3}' test.txt

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.1.2 打印文档第 1 列和第 3 列

# awk '{print $1,$3}' test.txt

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.1.3 打印文档第 1 列和第 3 列,但中间有很长的空格空间

# awk '{print $1,$3}' test.txt

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.1.4 打印倒数第 2 列

# awk '{print $(NF-2)}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.1.5 打印每一行的行号和列数

# awk -F: '{print NR,NF}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.1.6 打印前一个命令结果的第 5 列

# df -h | awk '{print $5}'

4.1.7 打印前一个命令结果的第 5 列

# df -h / | tail -1 | awk '{print $5}'

4.1.8 打印第 2 到最后 1 列

# cat test.txt | awk '{$1="";print}' | sed -r 's/( )(.*)/\2/'


补充:
1)这里的 /etc/passwd 是要被 awk 操作的测试文件
2)这里的 $1=”” 是将第一设置为空
3)这里的 print 作用相当于 print $0

4.1.9 打印每行的行数、列数、第 1 列和最后 1 列,并且将冒号 “:” 视为分割符

# awk -F: '{print NR,NF,$1,$NF}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.1.10 打印第 1 列,这里的 \047 代表的是单引号 “’”,并且将冒号 “:” 视为分割符

# awk -F: '{print "\047 $1 \047"}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.2 案例二:awk 替换打印
4.2.1 将第 1 列为 root 的行的第 3 列替换成 “1” 后打印,并且将冒号 “:” 视为分割符

# awk -F: '$1=="root"{ $3 = '1';print  }' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.2.2 将全部横杠 “-” 替换成空值后打印

# echo "z m y z-m-y 2021-11-11 z:y" | awk 'gsub(/-/,"")'
z m y zmy 20211111 z:y

或者:

# echo eternal-center-zmy | awk 'BEGIN{ FS="-";}{print $1,$2,$3}'
eternal center zmy

4.2.3 将全部横杠 “-” 替换成 3 个星号 “***” 后打印

# echo eternal-center-zmy | awk 'BEGIN{ FS="-";OFS="***"}{print $1,$2,$3}'
eternal***center***zmy

4.2.4 给每一行前面添加行号后打印

# cat test.txt 
eternalcenter.com-ec-myz
eternalcentre.com-ec-myz
eternalcenter.org-ec-myz
eternalcentre.org-ec-myz

# awk 'BEGIN{ OFS="." }{ print NR,$0}' test.txt 
1.eternalcenter.com-ec-myz
2.eternalcentre.com-ec-myz
3.eternalcenter.org-ec-myz
4.eternalcentre.org-ec-myz

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.2.5 以竖杠 “|” 作为分割符将第 2 列的数字去掉后打印

# cat test.txt 
eternalcenter.com|201901ec|com
eternalcentre.com|201902ec|com
zhumingyu.com|201903zmy|com
mingyuzhu.com|201904myz|com
eternalcenter.org|201905ec|org
eternalcentre.org|201906ec|org


# awk -F '|' 'BEGIN{ OFS="|" }{sub(/[0-9]+/,"",$2);print$0}' test.txt 
eternalcenter.com|ec|com
eternalcentre.com|ec|com
zhumingyu.com|zmy|com
mingyuzhu.com|myz|com
eternalcenter.org|ec|org
eternalcentre.org|ec|org

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

或者:

# cat test.txt 
eternalcenter.com|201901ec|com
eternalcentre.com|201902ec|com
zhumingyu.com|201903zmy|com
mingyuzhu.com|201904myz|com
eternalcenter.org|201905ec|org
eternalcentre.org|201906ec|org

# awk -F '|' -v OFS='|' '{sub(/[0-9]+/,"",$2);print $0}' test.txt 
eternalcenter.com|ec|com
eternalcentre.com|ec|com
zhumingyu.com|zmy|com
mingyuzhu.com|myz|com
eternalcenter.org|ec|org
eternalcentre.org|ec|org

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.2.6 将句号 “.” 替换成换行符后打印

# cat test.txt 
m.y.z

# awk 'BEGIN{RS=".";}{print $0}' test.txt 
m
y
z

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.2.7 将换行符替换成句号 “.” 后打印

# cat test.txt 
m
y
z


# awk 'BEGIN{ORS=".";}{print $0}' test.txt 
m.y.z.

(补充:这里的 test.txt 是要被 awk 操作的测试文件)

4.3 案例三:awk 变量
4.3.1 将 date 命令的运行结果,通过 getline 赋值给 d ,之后将 d 的值打印出来

# awk 'BEGIN {"date"|getline d; print d}'

4.3.2 将 eternalcenter 的值赋予给 content,并将 content 变量的值打印出来

# content=eternalcenter

# awk '{print "$content"}'
content

# awk '{print '$content'}'
eternalcenter

(补充:awk 在使用变量时必须使用单引号 “’”,否则会把变量名称当作字符串)

4.4 案例四:awk 自定义分割列符号
4.4.1 将冒号 ”:“ 视为分割符

# awk -F: '{print $1,$7}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.4.2 将冒号 ”:“ 和句号 “.” 视为分割符

# awk -F [:.] '{print $1,$10}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.5 案例五:awk 打印常量

# awk -F: '{print $1,"的解释器是:",$7}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6 案例六:awk 使用正则表达式匹配
4.6.1 打印包含 Failed 的行的第 11 列

# awk '/Failed/{print $11}' /var/log/secure

(补充:这里的 /var/log/secure 是要被 awk 操作的测试文件)

4.6.2 打印以 bash 结尾的行,并且将冒号 “:” 视为分割符

# awk -F: '/bash$/{print}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.3 打印以 root 或者 adm 开头的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '/^(root|adm)/{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.4 打印以 r 或者 a 开头的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '/^[ra]/{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.5 打印第 1 列包含 root 的行,并且将冒号 “:” 视为分割符

# awk -F: '$1~/root/' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.6 打印第 7 列不以 nologin 结尾的行的第 1 列和第 7 列,并且将冒号 “:” 视为分割符

# awk -F: '$7!~/nologin$/{print $1,$7}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.7 打印前一个命令包含 Rx p 的行的第 5 列

# ifconfig eth0 | awk '/RX p/{print $5}'

4.6.8 打印前一个命令以 / 结尾的行的第 4 列

# df -h | awk '/\/$/{print $4}'

4.6.9 打印第一列以两个数字结尾的行的第一列,并且将冒号 “:” 视为分割符

# awk -F: '$1 ~/[0-9][0-9]$/(print $1}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.6.10 打印以 root 开头到以 mysql 开头的所有行的第 1 列,并且将冒号 “:” 视为分割符

# awk -F '/^root/,/^mysql/{print $1}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7 案例七:awk 使用比较运算符匹配
4.7.1 打印行号等于 3 的行,并且将冒号 “:” 视为分割符

# awk -F: 'NR==3{print}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.2 打印第 3 列数值等于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '$3==1000{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.3 打印第 3 列数值不等于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '$3!=1000{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.4 打印第 3 列数值大于 1000 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '$3>=1000{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.5 打印第 3 列数值小于 10 的行的第 1 列和第 3 列,并且将冒号 “:” 视为分割符

# awk -F: '$3<10{print $1,$3}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.6 打印第 3 列数值大于 10 并且小于 20 的行,并且将冒号 “:” 视为分割符

# awk -F: '$3>10 && $3<20' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.7 打印第 3 列数值大于 1000 或者小于 10 的行,并且将冒号 “:” 视为分割符

# awk -F: '$3>1000 || $3<10' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.8 打印第 3 列乘以第 4 列小于 100 的行,并且将冒号 “:” 视为分割符

# awk -F: '$3 * $4 <100' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.7.9 打印第 1 列为 root 的行,并且将冒号 “:” 视为分割符

# awk -F: '$1=="root"' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.8 案例八:awk 计算
4.8.1 0 + 1 = 1

# awk 'BEGIN{print x+1}'

(注意:这里的 x 可以不定义,直接用,默认值为 0)

4.8.2 x = 0 + 1

# awk 'BEGIN{x++;print x}'

(注意:这里的 x 可以不定义,直接用,默认值为 0)

4.8.3 x = 8 + 2

# awk 'BEGIN{x=8;print x+=2}'

(注意:这里的 x 可以不定义,直接用,默认值为 0)

4.8.4 x = 8 – 1

# awk 'BEGIN{x=8;x--;print x}'

(注意:这里的 x 可以不定义,直接用,默认值为 0)

4.8.5 2 + 3 = 5

# awk 'BEGIN{print 2+3}'

4.8.6 2 * 3 = 6

# awk 'BEGIN{print 2*3}'

4.8.7 3.2 + 3.5 = 6.7

# awk 'BEGIN{print 3.2+3.5}'

4.8.8 23 除 8 余 7

# awk 'BEGIN{ print 23%8}'

4.8.9 打印第 3 加上 10 的结果,并且将冒号 “:” 视为分割符

# awk -F: '$3 + 10' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.8.10 找 200 以内 3 的倍数

# seq 200 | awk '$1%3==0'

4.8.11 找 100 以内 7 的倍数或者包含 7 的数

# seq 100 | awk '$1%7==0||$1~/7/'

4.8.12 将第 4 列求和后打印,并且将冒号 “:” 视为分割符

# awk -F: 'BEGIN{total=0}{total+=$4}END{print total}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9 案例九:awk 计数
4.9.1 计算以 bash 结尾的行数

# awk 'BEGIN{x=0}/bash$/{x++} END{print x}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9.2 计算第 3 列小于等于 1000 的行数,并且将冒号 “:” 视为分割符

# awk -F: '{if($3<=1000){i++}}END{print i}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9.3 计算 3 列大于 1000 的行数,并且将冒号 “:” 视为分割符

# awk -F: '{if($3>1000){i++}}END{print i}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9.4 计算第 7 列以 bash 结尾的行数,并且将冒号 “:” 视为分割符

# awk -F: '{if($7~/bash$/){i++}}END{print i}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9.5 计算第 3 列和第 4 列的和赋值给变量,将变量的值打印出来,并且将冒号 “:” 视为分割符

# awk -F: '{result=$3+$4; printf result}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.9.6 计算第 1 列所有值各自总共出现的次数

# awk '{a[$1]++}END{for(i in a){print i,a[$i]}}' /usr/local/nginx/logs/access.log

(补充:这里的 /usr/local/nginx/logs/access.log 是要被 awk 操作的测试文件)

4.9.7 统计此行中横杠 “-” 出现的次数并将第 4 列替换为次数

# echo "z- m y 2021-11-11 z:y" | awk '$4=gsub(/-/,"")'
z m y 3 z:y

4.10 案例十:awk if 判断语句计数
4.10.1 计算第 3 列小于等于 1000 的行数和第 3 列大于 1000 的行数,并且将冒号 “:” 视为分割符

# awk -F: '{if($3<=1000){i++}else{j++}}END{print i,j}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.10.2 计算第 7 列以 bash 结尾的行数和第 7 列不以 bash 结尾的行数,并且将冒号 “:” 视为分割符

# awk -F: '{if($7~/bash$/){i++}else{j++}} END{print i,j}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.10.3 如果第 3 列等于 0 则打印 “root”,否则打印 “not root”,并且将冒号 “:” 视为分割符

# awk -F: '{print ($3=0 ? "root": not root)}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.10.4 如果第 3 列大于 1000 则打印第 3 列的值,否则打印 “system id”,并且将冒号 “:” 视为分割符

# awk -F: 'BEGIN{max=1000}{id=($3>max ?$3 :"system id");print id}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.11 案例十一:awk for 循环实现同时批量输出值的名称和值
4.11.1 创建数组 a,其中 a[0]=0 a[1]=11 a[2]=22,并且将数组 a 打印出来

# awk 'BEGIN{a[0]=0;a[1]=11;a[2]=22; for(i in a){print i,a[i]}}'

4.11.2 统计所有的 IP 地址以及每一个 IP 地址访问的次数

# awk '{ip[$1]++} END{for(i in ip) {print i,ip[i] }}' /var/log/httpd/access_log


补充:
1) 这里的 /var/log/httpd/access_log 是要被 awk 操作的测试文件
2) 这里以统计 /var/log/httpd/access_log 文件里第一列的 IP 地址为例

4.11.3 统计所有的 IP 地址以及每一个 IP 地址访问的次数,并以从多到少的顺序进行排序

# awk '{ip[$1]++} END{for(i in ip) {print i,ip[i] }}' /var/log/httpd/access_log | sort -k2nr


补充:
1) 这里的 /var/log/httpd/access_log 是要被 awk 操作的测试文件
2) 这里以统计 /var/log/httpd/access_log 文件里第一列的 IP 地址为例

4.11.4 将每一列的值前面加上所属行的行号,按行打印出来

# awk -F: '{ i=1;while(i<NF) {print NR,$i;i++}}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.11.5 将每一列的值前面加上所属行的行号,按行打印出来

# awk '{ for(i=1;i<NF;i++)  {print NR,$i}}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

4.12 案例十二:awk 打印表格

在开始打印一行,在结尾打印一行,并且将 “:” 视为分割符

# awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1 "\t"  $3  "\t"  $6}END{print "Total",NR,"lines."}' /etc/passwd

(补充:这里的 /etc/passwd 是要被 awk 操作的测试文件)

[实验] Nginx 源码软件包的安装

纪念:站主于 2019 年 9 月完成了此开源实验,并将过程中的所有命令经过整理和注释以后,形成以下教程

软件准备:

在 Nginx 官网上下载搭建集群所需软件 Nginx:

http://nginx.org/en/download.html

正文:

步骤目录:

步骤一:系统环境要求

步骤二:安装 Nginx 的依赖软件

步骤三:安装 Nginx
3.1 添加一个用于启动 Nginx 的用户身份
3.2 解压 Nginx 安装包
3.3 进入 Nginx 安装包目录
3.4 配置 Nginx
3.5 编译并安装 Nginx

步骤四:测试 Nginx
4.1 启动 Nginx
4.2 访问 Nginx 实现的网页服务
4.3 查看已安装 Nginx 的版本

具体的操作步骤:

步骤一:系统环境要求

(1)服务器的系统需要是 CentOS 7 版本
(2)服务器系统需要有 yum 源

步骤二:安装 Nginx 的依赖软件

# yum -y install gcc pcre-devel openssl-devel

步骤三:安装 Nginx
3.1 添加一个用于启动 Nginx 的用户身份

# useradd -s /sbin/nologin nginx

3.2 解压 Nginx 安装包

# tar -xvf nginx-1.16.1.tar.gz

(补充:这里要安装的 Nginx 版本是 1.16.1)

3.3 进入 Nginx 安装包目录

# cd nginx-1.16.1

(补充:这里要安装的 Nginx 版本是 1.16.1)

3.4 配置 Nginx

# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

3.5 编译并安装 Nginx

# make && make install

步骤四:测试 Nginx
4.1 启动 Nginx

# /usr/local/nginx/sbin/nginx

4.2 访问 Nginx 实现的网页服务

# curl 127.0.0.1

4.3 查看已安装 Nginx 的版本

# /usr/local/nginx/sbin/nginx -V