Linux 正则表达式与文本三剑客完全指南
Linux 正则表达式
- 正则表达式作为一个
pattern,将pattern与要搜索的字符串进行匹配,以便查找一个或多个字符串。 - 正则表达式,自成体系,由普通字符(例如字符 a 到 z)和元字符组成的文字模式。
- 普通字符:没有显式指定为元字符的所有可打印和不可打印字符字符,包括所有大写和小写字母、所有数字、所有标点符号和其他一些符号。
- 元字符:出了普通字符之外的字符。
- 正则表达式,工具(vim、grep、less等)和程序语言(Perl、Python、C等)都使用正则表达式。
正则表达式分类:
- 普通正则表达式
- 扩展正则表示,支持更多的元字符。
环境准备
[root@server ~ 09:46:28]# cat > words <<EOF
> cat
> category
> acat
> concatenate
> cbt
> c1t
> cCt
> c-t
> c.t
> dog
> EOF
普通字符
[root@server ~ 10:04:57]# cat words | grep cat
cat
category
acat
concatenate
字符集
.
匹配除换行符(\n、\r)之外的任何单个字符,相等于[^\n\r]。
[root@server ~ 10:15:49]# cat words | grep 'c.t'
cat
category
acat
concatenate
cbt
c1t
cCt
c-t
c.t
[…]
匹配 [...] 中的任意一个字符。
[root@server ~ 10:16:00]# cat words | grep 'c[ab]t'
cat
category
acat
concatenate
cbt
[a-z] [A-Z] [0-9]
[a-z],匹配所有小写字母。[A-Z],匹配所有大写字母。[0-9],匹配所有数字。
[root@server ~ 10:16:23]# cat words | grep 'c[a-z]t'
cat
category
acat
concatenate
cbt
[root@server ~ 10:16:29]# cat words | grep 'c[A-Z]t'
cCt
[root@server ~ 10:16:35]# cat words | grep 'c[0-9]t'
c1t
[root@server ~ 10:16:40]# cat words | grep 'c[a-z0-9]t'
cat
category
acat
concatenate
cbt
c1t
[root@server ~ 10:16:49]# cat words | grep 'c[a-zA-Z0-9]t'
cat
category
acat
concatenate
cbt
c1t
cCt
# 要想匹配-符号,将改符号写在第一个位置
[root@server ~ 10:17:46]# cat words | grep 'c[-a-zA-Z0-9]t'
cat
category
acat
concatenate
cbt
c1t
cCt
c-t
[^…]
匹配除了 [...] 中字符的所有字符。
[root@server ~ 10:17:55]# cat words | grep 'c[^ab]t'
c1t
cCt
c-t
c.t
# ^放中间会被当做普通字符
[root@server ~ 10:18:11]# cat words | grep 'c[a^b]t'
cat
category
acat
concatenate
cbt
### \
将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。
例如, ‘n’ 匹配字符 ‘n’。\n 匹配换行符。序列 \\ 匹配 \,而 \( 则匹配 (。
[root@server ~ 10:18:34]# cat words | grep 'c\.t'
c.t
# 匹配普通字符,虽然可以匹配,但强烈建议不要在前面加\
[root@server ~ 10:18:50]# cat words | grep 'c\at'
cat
category
acat
concatenate
字符集总结
| 选项 | 描述 |
|---|---|
| [[:digit:]] | 数字: 0 1 2 3 4 5 6 7 8 9 等同于[0-9] |
| [[:xdigit:]] | 十六进制数字: 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f 等同于[0-9a-fA-F] |
| [[:lower:]] | 小写字母:在 C 语言环境和ASCII字符编码中,对应于[a-z] |
| [[:upper:]] | 大写字母:在 C 语言环境和ASCII字符编码中,对应于[A-Z] |
| [[:alpha:]] | 字母字符:[[:lower:]和[[:upper:]];在C语言环境和ASCII字符编码中,等同于**[A-Za-z]** |
| [[:alnum:]] | 字母数字字符:[:alpha:]和[:digit:];在C语言环境和ASCII字符编码中,等同于**[0-9A-Za-z]** |
| [[:blank:]]或者[[:space:]] | 空白字符:在 C 语言环境中,它对应于制表符、换行符、垂直制表符、换页符、回车符和空格。 |
| [[:punct:]] | 标点符号:在C语言环境和ASCII字符编码中,它对应于!" # $ % &'()*+,-./:;<=>?@[]^_`{|}~ |
| [[:print:]]或者 [[:graph:]] | 可打印字符: [[:alnum:]]、[[:punct:]]。 |
| [[:cntrl:]] | 控制字符。在 ASCII中, 这些字符对应八进制代码000到037和 177 (DEL)。 |
非打印字符
终端中不显示的字符,例如换行符。
| 字符 | 描述 |
|---|---|
| \cx | 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。 |
| \f | 匹配一个换页符。等价于 \x0c 和 \cL。 |
| \n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
| \r | 匹配一个回车符。等价于 \x0d 和 \cM。 |
| \s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。 |
| \S | 匹配任何**非空白字符**。等价于 [^ \f\n\r\t\v]。 |
| \w | 匹配字母、数字、下划线。等价于 [A-Za-z0-9_] |
| \W | 匹配任何非单词字符。等价于[^A-Za-z0-9_] |
| \t | 匹配一个制表符。等价于 \x09 和 \cI。 |
| \v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
grep 命令支持
\w、\W、\s、\S。
定位符
^
匹配行首位置。
[root@server ~ 10:19:03]# cat words |grep '^cat'
cat
category
$
匹配行末位置。
[root@server ~ 10:20:31]# cat words |grep 'cat$'
cat
acat
\b
匹配一个单词边界。
[root@server ~ 10:20:48]# echo hello cat kitty >> words
[root@server ~ 10:21:14]# cat words |grep '\bcat'
cat
category
[root@server ~ 10:21:32]# cat words |grep 'cat\b'
cat
acat
[root@server ~ 10:21:49]# cat words | grep '\bcat\b'
cat
hello cat kitty
\B
非单词边界匹配。
[root@server ~ 10:22:08]# cat words |grep '\Bcat\B'
concatenate
< 和 >
\<,匹配一个单词左边界。\>,匹配一个单词右边界。
[root@server ~ 10:23:04]# cat words |grep '\<cat'
cat
category
hello cat kitty
[root@server ~ 11:12:08]# cat words |grep 'cat\>'
cat
acat
hello cat kitty
限定次数
*
匹配前面的子表达式任意次数。
[root@server ~ 11:12:27]# echo dg>> words
[root@server ~ 11:12:55]# echo doog>> words
[root@server ~ 11:13:00]# cat words |grep 'do*g'
dog
dg
doog
+
+ 是扩展表达式元字符,匹配前面的子表达式一次以上次数。
[root@server ~ 11:13:52]# cat words | egrep 'do+g'
dog
doog
?
? 是扩展表达式元字符,匹配前面的子表达式一次以下次数。
[root@server ~ 11:13:58]# cat words | egrep 'do?g'
dog
dg
{n}
{} 是扩展表达式元字符,用于匹配特定次数。例如:{n},配置n次。
[root@server ~ 11:14:33]# cat words | egrep 'do{2}g'
doog
{m,n}
{m,n},是扩展表达式元字符,用于匹配次数介于m-n之间。
[root@server ~ 11:14:36]# echo dooog >> words
[root@server ~ 11:14:48]# echo doooog >> words
[root@server ~ 11:14:54]# cat words | grep 'do{2,3}g'
[root@server ~ 11:15:12]# cat words | egrep 'do{2,3}g'
doog
dooog
{m,}
{m,},是扩展表达式元字符,匹配前面的子表达式m次以上次数。
[root@server ~ 11:15:16]# cat words | egrep 'do{2,}g'
doog
dooog
doooog
{,n}
{,n},是扩展表达式元字符,匹配前面的子表达式n次以下次数。
[root@server ~ 11:15:29]# cat words | egrep 'do{,3}g'
dog
dg
doog
dooog
()
标记一个子表达式。
[root@server ~ 11:15:40]# echo dogdog >> words
[root@server ~ 11:15:50]# echo dogdogdog >> words
[root@server ~ 11:15:55]# echo dogdogdogdog >> words
[root@server ~ 11:15:59]# cat words | egrep '(dog){2,}'
dogdog
dogdogdog
dogdogdogdog
综合案例
如何过滤出以下内容中所有有效IPv4地址?
0.0.0.0
1.1.1.1
11.11.11.111
111.111.111.111
999.9.9.9
01.1.1.1
10.0.0.0
0.1.1.1
266.1.1.1
248.1.1.1
256.1.1.1
#解答
'^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
grep 工具使用手册
grep 介绍
grep 是 Linux 系统中最重要的命令之一,其功能是从文本文件或管道数据流中筛选匹配的行及数据。
Linux操作文本的三大利器,简称三剑客,分别是:
- grep:擅长过滤。
- sed:擅长修改文本。
- awk:擅长格式化输出。
grep 命令语法
- 过滤管道:
command | grep [OPTION]... PATTERNS - 过滤文件:
grep [OPTION]... PATTERNS [FILE]...
grep 命令选项
文件准备
[root@server ~ 11:17:35]$ vim words
cat
category
acat
concatenate
cbt
c1t
cCt
c-t
c.t
dog
模式选择和解释选项
-E 选项
支持扩展正则表达式,相当于 egrep 命令。
[root@server ~ 11:17:58]# cat words | grep -E '(dog){3}'
dogdogdog
dogdogdogdog
-e 选项
使用多个 -e 选项匹配多个PATTERNS。
[root@server ~ 13:50:06]# cat words | egrep 'cat|dog'
cat
category
acat
concatenate
dog
hello cat kitty
dogdog
dogdogdog
dogdogdogdog
-f 选项
从文件读取多个 PATTERNS。
[root@server ~ 13:50:37]# echo -e 'cat\ndog' > pattens_file
[root@server ~ 13:51:03]# cat pattens_file
cat
dog
[root@server ~ 13:51:10]# cat words | grep -f pattens_file
cat
category
acat
concatenate
dog
hello cat kitty
dogdog
dogdogdog
dogdogdogdog
-i 选项
忽略大小写匹配。
[root@server ~ 13:51:28]# cat words | grep -i 'cBt'
cbt
-w 选项
匹配整个单词。
[root@server ~ 13:51:47]# cat words | grep -w 'cat'
cat
hello cat kitty
-x 选项
匹配整行。
[root@server ~ 13:52:16]# cat words | grep -x 'cat'
cat
输出控制选项
-v 选项
反向匹配,显示与PATTERNS不匹配的项目。
[root@server ~ 13:52:36]# cat words | egrep -v '^d|^c'
acat
hello cat kitty
# 不看注释行和空白行
[root@server ~ 13:53:14]# egrep -v '^\s*# |^$' /etc/profile
-m 选项
控制最大匹配数目,匹配特定次数后停止匹配。
[root@server ~ 13:54:13]# cat words |grep 'dog'
dog
dogdog
dogdogdog
dogdogdogdog
[root@server ~ 13:54:24]# cat words | grep -m2 'dog'
dog
dogdog
-c 选项
显示匹配到项目的数量。
[root@server ~ 13:54:40]# cat words |grep -c 'dog'
4
-b 选项
显示匹配项目的字节偏移量。
[root@server ~ 13:55:01]# head -5 words
cat
category
acat
concatenate
cbt
[root@server ~ 13:55:11]# cat words |grep -b 'cat'
0:cat
4:category
13:acat
18:concatenate
54:hello cat kitty
-n 选项
显示匹配项目的行号。
[root@server ~ 13:55:24]# cat words |grep -n 'cat'
1:cat
2:category
3:acat
4:concatenate
11:hello cat kitty
-o 选项
只显示匹配到的内容,行中其他内容不显示。
[root@server ~ 13:55:32]# cat words |egrep '(dog){3}'
dogdogdog
dogdogdogdog
[root@server ~ 13:56:01]# cat words |egrep -o '(dog){3}'
dogdogdog
dogdogdog
-q 选项
不显示任何正常输出。一般用于脚本判定文件中是否包含特定内容。
通过特殊变量 $? 查看是否匹配到内容。
# 找到的情况
[root@server ~ 13:56:19]# cat words |egrep -q '(dog){3}'
[root@server ~ 13:57:16]# echo $?
0
# 找不到的情况
[root@server ~ 13:57:19]# cat words | egrep -q '(dog){3}asdfasfdasf'
[root@server ~ 13:57:56]# echo $?
1
查找文件选项
-r -R 选项
-r,递归匹配目录。-R,递归匹配目录,跟随软链接。
[root@server ~ 13:58:24]# grep -r '^SELINUX=' -s /etc
/etc/selinux/config:SELINUX=disabled
-h 和 -H 选项
-h,不显示匹配项目所在文件的文件名。-H,显示匹配项目所在文件的文件名,默认情况使用该选项。
[root@server ~ 14:14:17]# grep -r '^SELINUX=' -h /etc
SELINUX=disabled
[root@server ~ 14:14:47]# grep -r '^SELINUX=' -H /etc
/etc/selinux/config:SELINUX=disabled
-l 和 -L 选项
-l,对目录匹配时,只显示那些 包含匹配模式的文件的名称。-L,对目录匹配时,只显示那些 不 包含匹配模式的文件的名称。
[root@server ~ 14:14:51]# grep -r '^SELINUX=' -l /etc
/etc/selinux/config
[root@server ~ 14:15:04]# grep -r '^SELINUX=' -L /etc
/etc/fstab
/etc/crypttab
/etc/resolv.conf
/etc/grub.d/00_header
/etc/grub.d/01_users
/etc/grub.d/10_linux
......
输出内容控制选项
-B 选项
显示匹配项目本身,以及前多少行。
[root@server ~ 14:15:26]# ip addr | grep '10.1.8.10' -B2
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:1d:17:4e brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens33
-A 选项
显示匹配项目本身,以及后多少行。
[root@server ~ 14:15:33]# ip addr |grep 'ens33:' -A2
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:1d:17:4e brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens33
-C 选项
显示匹配项目本身,以及前后多少行。
[root@server ~ 14:15:57]# ip addr | grep '10.1.8.10' -C2
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:1d:17:4e brd ff:ff:ff:ff:ff:ff
inet 10.1.8.10/24 brd 10.1.8.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::73ae:4add:7559:5f94/64 scope link noprefixroute
sed 工具使用手册
sed 介绍
sed,英文全称 stream editor ,是一种非交互式的流编辑器,能够实现对文本非交互式的处理,功能很强大。
sed 是一个 70 后,诞生于 1973 - 1974 年间,具体时间未知。而出生地则是鼎鼎大名的 贝尔实验室。
sed 是 麦克马洪 ( McMahon ) 老爷子在 贝尔实验室 时开发出来的。
sed 的诞生使并不是那么的神秘,它的诞生只不过是 麦克马洪 ( McMahon ) 老爷子想写一个 行编辑器,谁知写着写着就写成了 sed 的样子。
其实,在 sed 之前还有一个更古老的行编辑器,名字叫做 ed 编辑器。大概是 麦克马洪 ( McMahon ) 老爷子觉得 ed 编辑器不好用吧,顺手重新构架和编写。
Linux操作文本的三大利器,简称三剑客,分别是:
- grep:擅长过滤。
- sed:擅长修改文本。
- awk:擅长格式化输出。
sed 与 awk 并称为 Linux/Unix 世界的两大王牌文字处理器:
- sed 侧重点是替换。
- awk 侧重点是分割和重新合成。
sed 工作流程
读取行 -> 执行 -> 显示 -> 读取行 -> 执行 -> 显示 -> .... -> 读取行 -> 执行 -> 显示

- 读取行
sed 从输入流 (文件、管道、标准输入流)中读取 一行 并存储在名叫 pattern space 的内部空间中。
sed 是行文字处理器。每次只会读取一行。
sed 内部会有一个计数器,记录着当前已经处理多少行,也就是当前行的行号。
- 执行
按照 sed 命令定义的顺序依次应用于刚刚读取的 一行 数据。
默认情况下,sed 一行一行的处理所有的输入数据。但如果我们指定了行号,则只会处理指定的行。
- 显示
把经过 sed 命令处理的数据发送到输出流(文件、管道、标准输出),并同时清空 pattern space 空间。
- 上面流程一直循环,直到输入流中的数据全部处理完成。
sed 注意事项
整个流程看似简单,有几个知识点需要注意:
pattern space空间是 sed 在内存中开辟的一个私有的存储区域。内存的特性,会导致关闭命令行或关机数据就没了。- 默认情况下,sed 命令只会处理
pattern space空间中的数据,且并不会将处理后的数据保存到源文件中。也就是说,sed 默认并不会修改源文件。
但 GNU SED 提供提供了一种方式用于修改 源文件。方式就是传递 -i 选项,在后面的章节中介绍。
- sed 还在内存上开辟了另一个私有的空间
hold space用于保存处理后的数据以供以后检索。
每一个周期执行结束,sed 会清空 pattern space 空间的内容,但 hold space 空间的内容并不会清空。hold space 空间用于存储处理后数据,sed 命令并不会对这里的数据处理。
这样,当 sed 需要之前处理后的数据时,可以随时从 hold space 空间读取。
- sed 程序执行前,模式
pattern和hold space空间都是空的。 - 如果我们没有传递任何输入文件,sed 默认会从 标准输入 中读取数据。
- sed 可以指定只处理输入数据中的行范围。默认情况下是全部行,因此会依次处理每一行。
sed 命令语法
sed 帮助
[root@server ~ 14:25:26]$ sed --help
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
-n, --quiet, --silent
suppress automatic printing of pattern space
-e script, --expression=script
add the script to the commands to be executed
-f script-file, --file=script-file
add the contents of script-file to the commands to be executed
--follow-symlinks
follow symlinks when processing in place
-i[SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if SUFFIX supplied)
-c, --copy
use copy instead of rename when shuffling files in -i mode
-b, --binary
does nothing; for compatibility with WIN32/CYGWIN/MSDOS/EMX (
open files in binary mode (CR+LFs are not treated specially))
-l N, --line-length=N
specify the desired line-wrap length for the `l' command
--posix
disable all GNU extensions.
-r, --regexp-extended
use extended regular expressions in the script.
-s, --separate
consider files as separate rather than as a single continuous
long stream.
-u, --unspaceed
load minimal amounts of data from the input files and flush
the output spaces more often
-z, --null-data
separate lines by NUL characters
--help
display this help and exit
--version
output version information and exit
If no -e, --expression, -f, or --file option is given, then the first
non-option argument is taken as the sed script to interpret. All
remaining arguments are names of input files; if no input files are
specified, then the standard input is read.
GNU sed home page: <http://www.gnu.org/software/sed/>.
General help using GNU software: <http://www.gnu.org/gethelp/>.
E-mail bug reports to: <bug-sed@gnu.org>.
Be sure to include the word ``sed'' somewhere in the ``Subject:'' field.
-n, --quiet, --silent 取消自动打印模式空间
-e 脚本, --expression=脚本 添加“脚本”到程序的运行列表
-f 脚本文件, --file=脚本文件 添加“脚本文件”到程序的运行列表
--follow-symlinks 直接修改文件时跟随软链接
-i[扩展名], --in-place[=扩展名] 直接修改文件(如果指定扩展名就备份文件)
-l N, --line-length=N 指定“l”命令的换行期望长度
--posix 关闭所有 GNU 扩展
-r, --regexp-extended 在脚本中使用扩展正则表达式
-s, --separate 将输入文件视为各个独立的文件而不是一个长的连续输入
-u, --unspaceed 从输入文件读取最少的数据,更频繁的刷新输出
--help 打印帮助并退出
--version 输出版本信息并退出
-a ∶新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
-c ∶取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
-d ∶删除,因为是删除啊,所以 d 后面通常不接任何咚咚;
-i ∶插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
-p ∶列印,亦即将某个选择的资料印出。通常 p 会与参数 sed -n 一起运作~
-s ∶取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法
sed 命令语法简写格式如下:
sed [option] [sed-command] [input-file]
总的来说 sed 命令主要由四部分构成:
sed命令。[option]命令行选项,用于改变 sed 的工作流程。[sed-command]是具体的 sed 命令。[input-file]输入数据,如果不指定,则默认从标准输入中读取。
示例1:模拟cat命令打印文件内容
[root@server ~ 14:46:34]# cat > data.txt <<'EOF'
> I am studing sed
> I am www.laoma.cloud
> I am a Superman
> I am so handsome
> EOF
[root@server ~ 15:00:37]# sed "data.txt
> I am studing sed
> I am www.laoma.cloud
> I am a Superman
> I am so handsome
对照着 sed 命令的语法格式:
- 这里未使用
option。 '',对应着[sed-command]为具体的 sed 语句。data.txt,对应着[input-file],用于提供输入数据。
示例2:从标准输入中读取数据
如果我们没有提供输入文件,那么 sed 默认会冲标准输入中读取数据。
[root@server ~ 15:01:09]# sed ''
#输入任意字符串回车
hello
hello
hi
hi
# 输出hello world
hello world
# 按ctrl+d推出
-e 选项
从命令行读取sed命令,我们需要将 sed 命令使用单引号 ( '' ) 引起来。
# 打印data.txt文件内容
[root@server ~ 15:01:51]# sed -e '' data.txt
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome
# 如果只有一个命令,-e选项可以省略
[root@server ~ 15:01:58]# sed '' data.txt
I am studing sed
I am www.laoma.cloud
I am a Superman
I am so handsome
# -e 选项可以多次使用,1d是作用是删除第一行
[root@server ~ 15:02:33]# sed -e '1d' -e '2d' -e '5d' data.txt
I am a Superman
I am so handsome
# 因为不存在第五行,所以也就没删除的效果
# 使用分号(;)分开多个命令
[root@server ~ 15:02:57]# sed -e '1d;2d;5d' data.txt
I am a Superman
I am so handsome
-f 选项
sed 还支持把所有 sed 命令保存在一个普通的文本文件里,然后通过 -f 选项来运行这个文件。
当把 sed 存储在文件中时,需要注意 每一个 sed 命令独自成一行。
文件的作用仅仅用于存储命令而已,因此存储 sed 命令的文件并没有任何特殊,可以是一个 .txt 文本文件。
[root@server ~ 15:03:23]# echo -e "1d\n2d\n5d" > scripts
[root@server ~ 15:03:49]# cat scripts
1d
2d
5d
[root@server ~ 15:03:53]# sed -f scripts data.txt
I am a Superman
I am so handsome
-n 选项
如果指定了该选项,那么模式空间数据将不会自动打印,需要明确指明打印才会输出记录。
# 以下命令没有任何输出
[root@server ~ 15:04:04]# sed -n '' data.txt
# 打印第一行记录
[root@server ~ 15:04:24]# sed -n '1p' data.txt
I am studing sed
sed 行寻址
作用
通过行寻址匹配要处理的输入流。
语法
这里以打印命令p为例。
语法:[address1[,address2]]p
address1和address2分别是 起始地址 和 结束地址,可以是 行号或 模式字符串。address1和address2都是可选参数,可以都不填,这时候就是打印所有行,从文件的开头到文件结束。- 如果存在一个,那么就是打印 单行。也就是只打印
address1指定的那行。 p命令仅从 模式缓冲区 中打印行,也就是该行不会发送到输出流,原始文件保持不变。
示例文件
[root@server ~ 15:04:32]# echo 'This is 1
> This is 2
> This is 3
> This is 4
> This is 5 ' > test
演示
示例1: 打印所有行
# 打印所有行
[root@server ~ 15:05:49]# cat test |sed ''
This is 1
This is 2
This is 3
This is 4
This is 5
# sed 默认打印模式缓冲区中所有内容。
# 等效于
[root@server ~ 15:06:00]# cat test |sed -n 'p'
This is 1
This is 2
This is 3
This is 4
This is 5
# -n 关闭sed打印模式缓冲区中所有内容。
# p命令,明确打印输出模式缓冲区中所有内容。
示例2: 打印特定行
# 打印第1行
[root@server ~ 15:06:09]# cat test |sed -n '1p'
# 输出结果
This is 1
# 打印第最后一行
[root@server ~ 15:06:13]# cat test |sed -n '$p'
# 输出结果
This is 5
示例3: 打印第1行到3行
[root@server ~ 15:06:17]# cat test |sed -n '1,3p'
# 输出结果
This is 1
This is 2
This is 3
示例4: 打印第3行到最后一行
[root@server ~ 15:06:22]# cat test |sed -n '3,$p'
# 输出结果
This is 3
This is 4
This is 5
示例5: 连续输出,打印第2行以及后续两行
[root@server ~ 15:06:27]# cat test |sed -n '2,+2p'
# 输出结果
This is 2
This is 3
This is 4
示例6: 隔行输出,打印第1行以及后续隔2行输出
[root@server ~ 15:06:34]# cat test |sed -n '1~2p'
# 输出结果
This is 1
This is 3
This is 5
sed 模式寻址
sed 除了可以从行号来选择行,s还支持模式查找指定的行。
- 模式 可以是一个普通的字符串或者一个正则表达式。
- 模式 的语法和行寻址的语法类似,只是把行号换成了 模式 匹配。
例如,输出匹配指定模式的行,语法格式如下:
/pattern/
示例文件
[root@server ~ 15:06:40]# cat << 'EOF' > ~/test
> root:x:0:0:root:/root:/bin/bash
> bin:x:1:1:bin:/bin:/bin/false
> daemon:x:2:2:daemon:/sbin:/bin/false
> mail:x:8:12:mail:/var/spool/mail:/bin/false
> ftp:x:14:11:ftp:/home/ftp:/bin/false
> &nobody:$:99:99:nobody:/:/bin/false
> zhangy:x:1000:100:,,,:/home/zhangy:/bin/bash
> http:x:33:33::/srv/http:/bin/false
> dbus:x:81:81:System message bus:/:/bin/false
> hal:x:82:82:HAL daemon:/:/bin/false
> mysql:x:89:89::/var/lib/mysql:/bin/false
> aaa:x:1001:1001::/home/aaa:/bin/bash
> ba:x:1002:1002::/home/zhangy:/bin/bash
> test:x:1003:1003::/home/test:/bin/bash
> @zhangying:*:1004:1004::/home/test:/bin/bash
> policykit:x:102:1005:Po
> EOF
演示
示例1: 打印含有字符串zhang的行
[root@server ~ 15:07:07]# cat test |sed -n '/zhang/p'
zhangy:x:1000:100:,,,:/home/zhangy:/bin/bash
ba:x:1002:1002::/home/zhangy:/bin/bash
@zhangying:*:1004:1004::/home/test:/bin/bash
示例2: 打印root开头的行到zhang开头的行
[root@server ~ 15:07:29]# cat test |sed -n '/^root/,/^mail/p'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
mail:x:8:12:mail:/var/spool/mail:/bin/false
示例3: 打印root开头的行到第三行
[root@server ~ 15:07:54]# cat test |sed -n '/^root/,3p'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
示例4: 打印root开头的行到最后一行
[root@server ~ 15:08:05]# cat test |sed -n '/^root/,$p'
sed 子命令
打印
作用
- p,打印模式空间所有记录。
- P,打印模式空间第一行记录。
语法
格式:[address1[,address2]]p
address1和address2分别是 起始地址 和 结束地址,可以是 行号或 模式字符串。address1和address2都是可选参数,可以都不填,这时候就是打印所有行,从文件的开头到文件结束。- 如果存在一个,那么就是打印 单行。也就是只打印
address1指定的那行。 p命令仅从 模式缓冲区 中打印行,也就是该行不会发送到输出流,原始文件保持不变。
读取下一行
- n,提前读取下一行,覆盖模型空间之前读取的行。模型空间之前读取的行并没有删除,依然打印至标准输出,除非使用-n选项指明不打印。
说明:
- 读取
This is 1,执行n命令,此时模式空间为This is 2,执行p,打印模式空间内容This is 2。 - 之后读取
This is 3,执行 n 命令,此时模式空间为This is 4,执行p,打印模式空间内容This is 4。 - 之后读取
This is 5,执行 n 命令,因为后续没有内容了,所以退出,并放弃p命令。
因此,最终打印出来的就是偶数行。
- N,简单来说就是追加下一行到模式空间,同时将两行看做一行,但是两行之间依然含有\n换行符。
说明:
N,追加下一行到当前行后面,组成一个新行来处理。s/\n/==/,将新行中\n换行符替换成==,末尾的换行符不替换。
替换
**示例1:**把test文件中的root替换成tankzhang,只不过只替换一次即终止在这一行的操作,并转到下一行
[root@server ~ 15:08:30]# sed 's/root/tankzhang/' test |grep tankzhang
tankzhang:x:0:0:root:/root:/bin/bash
关闭 SELinux
[root@server ~ 15:11:08]# sed -i 's/^SELINUX=.*/SELINUX=disabled/g' config
**示例2:**把test文件中的root全部替换成tankzhang。字母g是global的缩写。
[root@server ~ 15:11:36]# sed 's/root/tankzhang/g' test |grep tankzhang
tankzhang:x:0:0:tankzhang:/tankzhang:/bin/bash
**示例3:**加了-n和p后表示只打印那些发生替换的行(部分替换),下面的例子,不需要使用grep命令。
[root@server ~ 15:11:50]# sed -n 's/root/tankzhang/p' test
tankzhang:x:0:0:root:/root:/bin/bash
**示例4:**加了-n和pg后表示只打印那些发生替换的行(全部替换)
[root@server ~ 15:11:50]# sed -n 's/root/tankzhang/p' test
tankzhang:x:0:0:root:/root:/bin/bash
**示例5:**在第二行到第八行之间,替换以zhang开头的行,用ying来替换,并显示替换的行
[root@server ~ 15:12:10]# sed -ne '2,8s/^zhang/ying/gp' test
yingy:x:1000:100:,,,:/home/zhangy:/bin/bash
示例6: 从以zhang开头的行开始,到匹配Po的行结束,在他们之间进行替换
[root@server ~ 15:13:10]# sed -ne '/^zhang/,/Po/ s/zhang/ying/gp' test
yingy:x:1000:100:,,,:/home/yingy:/bin/bash
ba:x:1002:1002::/home/yingy:/bin/bash
@yingying:*:1004:1004::/home/test:/bin/bash
替换中的分隔符可以自定义,默认是/。
示例7: 自定义替换分隔符为 #。
[root@server ~ 15:14:00]# sed -n 's#root#hello#gp' test
hello:x:0:0:hello:/hello:/bin/bash
分隔符 ; 和 -e 选项
需要执行多个sed处理命令时,用分号分开,或者使用 -e 选项。
示例:
- 在第2行到第8行之间,替换以zhang开头的行,用ying来替换
- 在第5行到第10行之间,用goodbay来替换dbus,并显示替换的行
[root@server ~ 15:14:15]# cat test | sed -n '2,8s/^zhang/ying/gp;5,10s#dbus#goodbay#gp'
yingy:x:1000:100:,,,:/home/zhangy:/bin/bash
goodbay:x:81:81:System message bus:/:/bin/false
[root@server ~ 15:15:02]# cat test | sed -ne '2,8s/zhang/ying/gp' -ne '5,10s#dbus#goodbay#gp'
yingy:x:1000:100:,,,:/home/yingy:/bin/bash
goodbay:x:81:81:System message bus:/:/bin/false
插入
a(append) 在匹配行下面插入新行
[root@server ~ 15:15:09]# sed '/root/a====aaaa===='test
root:x:0:0:root:/root:/bin/bash
====aaaa====
bin:x:1:1:bin:/bin:/bin/false
......
i(insert) 在匹配行上面插入新行
[root@server ~ 15:15:56]# sed '/root/i====iiii====' test
====iiii====
root:x:0:0:root:/root:/bin/bash
.....
删除
作用
- d,删除模式空间所有记录。
- D,删除模式空间第一行记录。
语法
d 格式:[address1[,address2]]d
D 格式:[address1[,address2]]D
address1和address2分别是 起始地址 和 结束地址,可以是 行号或 模式字符串。address1和address2都是可选参数,可以都不填,这时候就是删除所有行,从文件的开头到文件结束。- 如果存在一个,那么就是删除 单行。也就是只删除
address1指定的那行。 d命令仅从 模式缓冲区 中删除行,也就是该行不会发送到输出流,原始文件保持不变。
d 删除 示例
示例1: 删除1-14行
[root@server ~ 19:14:02]# sed -e '1,14d' test
@zhangying:*:1004:1004::/home/test:/bin/bash
policykit:x:102:1005:Po
示例2: 删除4以后的行,包括第4行,把$当成最大行数就行了。
[root@server ~ 19:14:05]# sed -e '4,$d' test
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
示例3: 删除包括false的行,或者包括bash的行,别忘了加\
[root@server ~ 19:14:17]# sed -re '/(false|bash)/d' test
policykit:x:102:1005:Po
示例4: 删除从匹配root的行,到匹配以test开头的行,中间的行
[root@server ~ 19:14:27]# sed -e '/root/,/^test/d' test
@zhangying:*:1004:1004::/home/test:/bin/bash
policykit:x:102:1005:Po
更改
整行替换。
示例:root开头行替换成hello
[root@server ~ 19:14:35]# sed '/^root/chello' test
hello
bin:x:1:1:bin:/bin:/bin/false
daemon:x:2:2:daemon:/sbin:/bin/false
mail:x:8:12:mail:/var/spool/mail:/bin/false
ftp:x:14:11:ftp:/home/ftp:/bin/false
&nobody:$:99:99:nobody:/:/bin/false
......
# 等效下面命令
[root@server ~ 19:14:55]# sed 's/^root.*/hello/' test
awk 工具使用手册
awk 介绍
awk 是一个强大的文本分析工具。
awk 是取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
awk 更像一门编程语言,他可以自定义变量,有条件语句,有循环,有数组,有正则,有函数等。
awk 按行读取数据,根据给出的条件进行查找,并在找出来的行中进行操作。
awk 命令
awk 命令格式
awk [options] 'script' file(s)
awk [options] -f scriptfile file(s)
script,定义如何处理数据。file,是 awk 处理的数据来源,awk 也可以来自其它命令的输出。-f scriptfile从脚本文件中读取awk命令,每行都是一个独立的script。
script 格式如下:
BEGIN { action }
pattern { action }
END { action }
脚本通常是被单引号或双引号包住,一个awk脚本通常由四部分组成:
BEGIN { action }语句块,awk 执行pattern { action }前要执行的脚本。pattern { action }语句块,决定动作语句何时触发,可以是以下任意一种: - 正则表达式:使用通配符的扩展集。 - 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。 - 模式匹配表达式:使用运算符~(匹配)和~!(不匹配)。END { action }语句块,awk 执行pattern { action }后要执行的脚本。- action部分,决定对数据如何处理,由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大刮号内。常见的action包括:变量或数组赋值、输出命令、内置函数、控制流语句。
BEGIN { action }、pattern { action }、END { action }都是可选项目。
awk 工作流

- 第一步: 执行
BEGIN { commands }语句块中的语句。
在awk从输入输出流中读取行之前执行,通常在BEGIN语句块中执行如变量初始化,打印输出表头等操作。
- 第二步:**从文件或标准输入中读取一行,然后执行
pattern { commands }语句块。**它逐行读取数据,从第一行到最后一行重复这个过程,直到读取完所有行。
pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行。
{} 类似一个循环体,会对文件中的每一行进行迭代,通常将变量初始化语句放在BEGIN语句块中,将打印结果等语句放在END语句块中。
- 第三步:当读至输入流末尾时,执行
END { command }语句块。
在awk从输入流中读取完所有的行之后执行,比如打印所有行的分析结果,它也是一个可选语句块。
awk 示例
示例文件
[root@server ~ 19:15:05]# cat << 'EOF' > employee.txt
> 1) 张三 技术部 23
> 2) 李四 人力部 22
> 3) 王五 行政部 23
> 4) 赵六 技术部 24
> 5) 朱七 客服部 23
> EOF
示例1: 打印雇员信息。
[root@server ~ 19:15:30]# awk '{ print }' employee.txt
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
示例2: 通过读取awk脚本,打印雇员信息。
[root@server ~ 19:15:40]# cat commands.awk
{ print }
[root@server ~ 19:15:55]# awk -f commands.awk employee.txt
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
示例3: 输出特定隔行。
[root@server ~ 19:16:12]# awk '/张三/ { print }' employee.txt
1) 张三 技术部 23
# 等同于
[root@server ~ 19:16:27]# awk '/张三/' employee.txt
1) 张三 技术部 23
示例5: 输出总长度大于 10 的行。
AWK 提供了一个内建的函数 **length(arg)∗∗用于返回字符串‘arg)** 用于返回字符串 `arg)∗∗用于返回字符串‘arg` 的总长度。
如果要获取某行的总长度,可以使用下面的语法:
length($0)。同样的,如果要获取某列/字段的总长度,可以使用语法:
length($n)。如果要判断某行的字符是否大于/小于/等于 N ,可以使用下面的语法:
length($0) > N。
[root@server ~ 19:17:14]# awk 'length($0)>10 { print $0 }' employee.txt
因为所有的行的总长度都大于 18,因此输出结果如下:
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
awk 综合示例
雇员信息表如下:
[root@server ~ 19:17:15]# cat employee.txt
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
示例文件结构:
- 每个雇员独占一行
- 每个雇员都包括以下字段:序号,名字,部门,年龄
- 每一行的多个字段之间使用空白作为分隔符,空白分隔符一般是空格 ( ) 或者制表符
\t
问题
我们想要获得以下输入结果
序号 姓名 部门 年龄
-------------------
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
-------------------
分析
从上面的结果中可以看出,整个输出结果分为三大部分
- 表头
```序号 姓名 部门 年龄
```
- 数据
每个雇员一样,且有着以下的结构
1) 张三 技术部 23 2) 李四 人力部 22 3) 王五 行政部 23 4) 赵六 技术部 24 5) 朱七 客服部 23
- 表尾
```
```
根据我们刚刚学到的知识,AWK 程序结构分为三大部分,BEGIN 和 END 只会执行一次,看起来刚好可以用来输出表头,而 AWK 主体代码,是针对每一行执行的,因此,刚好可以用来输出数据。
解答
表头
为了输入表头,我们可以使用下面的 Shell 语句
[root@server ~ 19:18:20]# awk '
> BEGIN { printf "序号\t名字\t部门\t年龄\n-------------------\n" }'
因为表头部分不需要处理输入文件,也不需要处理输入文件中的每一行,所以 AWK 主体代码都是可以忽略的,甚至包括输入文件都是可以忽略的。
运行以上代码,输出结果如下:
序号 名字 部门 年龄
-------------------
数据
对比想要的结果和输入的文件,可以看出输出结果并并没有对每一行做特殊处理,直接显示就好
因此,只需要在 BEGIN 块后面直接添加 { print } ,添加完代码如下:
[laoma@shell ~]$ cat employee.txt | awk '
BEGIN { printf "序号\t名字\t部门\t年龄\n-------------------\n" }
{ print }
END {printf "-------------------\n"}'
运行以上代码,输出结果如下:
序号 名字 部门 年龄
-------------------
1) 张三 技术部 23
2) 李四 人力部 22
3) 王五 行政部 23
4) 赵六 技术部 24
5) 朱七 客服部 23
-------------------
-F 选项
**作用:**用于定义awk程序的分隔符。awk程序的分隔符,是用于分割同一行数据的分割符号。默认分隔符是:空格。
语法:-F fs 或者 --field-separator=fs
**示例:**打印用户名和家目录
[root@server ~ 19:18:26]# head -n1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@server ~ 19:19:20]# head -n1 /etc/passwd | awk -F : '{ print $1" "$6 }'
root /root
-v 选项
**作用:**用于预定义一些变量。这些预定义变量会在执行AWK 程序之前就定义好,准确的说,在 BEGIN 语句之前就已经定义。
- 定义内部变量接收外部变量。
```bash [laoma@shell ~]$ var1=“aaa” [laoma@shell ~]$ var2=“bbb” [laoma@shell ~]$ echo | awk ‘{ print v1,v2 }’ v1=var1v2=var1 v2=var1v2=var2 aaa bbb
# 输入来自文件时 [laoma@shell ~]$ awk ‘{ print v1,v2 }’ v1=var1v2=var1 v2=var1v2=var2 /etc/hostname aaa bbb ```
-p 选项
**作用:**用于将当前的 awk 程序代码格式化并且输出到 file 文件中。
格式:--profile[=file] 或者 -p[file]
awk默认导出的 awk 程序代码格式化代码到 awkvars 文件中。
示例:
[root@server ~ 19:20:12]# awk --profile '
> BEGIN { printf"---|Header|--\n" }
> { print }
> END { printf"---|Footer|---\n" }' employee.txt > /dev/null
运行上面的 awk 程序,awkprof.out 内容如下:
# gawk profile, created Wed Aug 20 11:36:46 2025
# BEGIN block(s)
BEGIN {
printf "---|Header|--\n"
}
# Rule(s)
{
print $0
}
# END block(s)
END {
printf "---|Footer|---\n"
}
awk 内置变量
在上述的示例中,我们使用了很多 awk 内置变量。
我们可以使用 -d 选项,导出awk内置的预定义变量到 file 文件中。
格式:--dump-variables[=file] 或者-d[file]
awk默认导出的内置的预定义变量保存在文件 awkvars 文件中。
示例:
[root@server ~ 19:20:27]# awk -d ''
[root@server ~ 19:20:50]# cat awkvars.out
ARGC: 1
ARGIND: 0
ARGV: array, 1 elements
BINMODE: 0
CONVFMT: "%.6g"
ERRNO: ""
FIELDWIDTHS: ""
FILENAME: ""
FNR: 0
FPAT: "[^[:space:]]+"
FS: " "
IGNORECASE: 0
LINT: 0
NF: 0
NR: 0
OFMT: "%.6g"
OFS: " "
ORS: "\n"
RLENGTH: 0
RS: "\n"
RSTART: 0
RT: ""
SUBSEP: "\034"
TEXTDOMAIN: "messages"
我们把上面的输出结果整理如下:
| 变量 | 数据类型 | 默认值 |
|---|---|---|
| ARGC | number | 1 |
| ARGIND | number | 0 |
| ARGV | array | 1 elements |
| BINMODE | number | 0 |
| CONVFMT | string | “%.6g” |
| ERRNO | number | 0 |
| FIELDWIDTHS | string | “” |
| FILENAME | string | “” |
| FNR | number | 0 |
| FS | string | " " |
| IGNORECASE | number | 0 |
| LINT | number | 0 |
| NF | number | 0 |
| NR | number | 0 |
| OFMT | string | “%.6g” |
| OFS | string | " " |
| ORS | string | “\n” |
| RLENGTH | number | 0 |
| RS | string | “\n” |
| RSTART | number | 0 |
| RT | string | “” |
| SUBSEP | string | “\034” |
| TEXTDOMAIN | string | “messages” |
上面列出的这些变量,在 AWK 中扮演整重要的作用。
| 变 量 | 描述 |
|---|---|
| ARGC | 命令行参数的数目。 |
| ARGIND | 命令行中当前文件的位置(从0开始算)。 |
| ARGV | 包含命令行参数的数组。 |
| CONVFMT | 数字转换格式(默认值为%.6g) |
| ENVIRON | 环境变量关联数组。 |
| ERRNO | 最后一个系统错误的描述。 |
| FIELDWIDTHS | 字段宽度列表(用空格键分隔)。 |
| FILENAME | 当前文件名。 |
| FNR | 同NR,但相对于当前文件。 |
| FS | 字段分隔符(默认是任何空格)。 |
| IGNORECASE | 如 果为真,则进行忽略大小写的匹配。 |
| NF | 当前记录中的字段数。 |
| NR | 当前记录数(读入第几行数据)。 |
| OFMT | 数字的输出格式(默认值是%.6g)。 |
| OFS | 输 出字段分隔符(默认值是一个空格)。 |
| ORS | 输出记录分隔符(默认值是一个换行符)。 |
| RLENGTH | 由 match函数所匹配的字符串的长度。 |
| RS | 记录分隔符(默认是一个换行符)。 |
| RSTART | 由 match函数所匹配的字符串的第一个位置。 |
| SUBSEP | 数组下标分隔符(默认值是\034)。 |
| $n | 当前记录的第n个字段,字段间由 FS分隔。 |
| $0 | 完整的输入记录。 |
NF 变量
变量 NF 是 Number of Fields 的缩写,用于表示当前行分割出来的字段/列数量。
下面的命令输出了当前每一行有被分割出了多少个字段。
[root@server ~ 19:20:54]# echo -e "一 二\n一 二 三\n一 二 三 四" | awk '{ print $0 "\t",NF }'
运行以上代码,输出结果如下:
一 二 2
一 二 三 3
一 二 三 四 4
变量 NF 还可以用于条件判断。
例如,下面的命令输出了哪些字段/列大于 2 的行。
[root@server ~ 19:21:08]# echo -e "一 二\n一 二 三\n一 二 三 四" | awk 'NF > 2'
运行以上代码,输出结果如下:
一 二 三
一 二 三 四
NR 变量
变量 NR 是 Number of Record 的缩写,用于表示当前行的行号,也就是处理到第几行。行编号从 1 开始。
下面的代码,用于在每一行数据的前面输出当前的行号
[root@server ~ 19:21:17]# echo -e "一 二\n一 二 三\n一 二 三 四" | awk '{ print NR". "$0 }'
运行以上代码,输出结果如下:
1. 一 二
2. 一 二 三
3. 一 二 三 四
变量 NR 还可以用于条件判断,例如下面的命令用于输出行号小于 3 的行,也就是第一第二行。
[root@server ~ 19:21:27]# echo -e "一 二\n一 二 三\n一 二 三 四" | awk 'NR < 3'
运行以上代码,输出结果如下:
一 二
一 二 三
$N
对于 AWK 来说,默认的分割符是空白符号,包括 “\t” 和空格 " "。当 AWK 使用分割符对每一行进行分割后,会对每一列/字段进行编号:
$1 $2 $3 ...,分别代表第1列,第2列,第3列…$0,代表一整行。
示例1:
[root@server ~ 19:21:44]# head -n1 /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@server ~ 19:21:57]# head -n1 /etc/passwd |awk '{ print $0 }'
root:x:0:0:root:/root:/bin/bash
[root@server ~ 19:22:19]# head -n1 /etc/passwd |awk -F : '{ print $1" "$6 }'
root /root
示例2: 统计 /usr/share/doc 目录下文件size最大的前10个,并显示文件size。
[root@server ~ 19:22:28]# sudo find /usr/share/doc -type f -ls | awk '{print $7,$11}' | sort -nr | head
725773 /usr/share/doc/rpm-4.11.3/ChangeLog.bz2
588023 /usr/share/doc/rsyslog-8.24.0/ChangeLog
548330 /usr/share/doc/xz-5.2.2/ChangeLog
521349 /usr/share/doc/yum-3.4.3/ChangeLog
509135 /usr/share/doc/grub2-common-2.02/grub.html
486761 /usr/share/doc/man-db-2.6.3/ChangeLog
412827 /usr/share/doc/tar-1.26/ChangeLog
411052 /usr/share/doc/findutils-4.5.11/ChangeLog
379303 /usr/share/doc/glib2-2.56.1/NEWS
360877 /usr/share/doc/parted-3.1/ChangeLog
# 如何让文件的单位使用human size显示?
[root@server ~ 19:22:37]# sudo find /usr/share/doc -type f -ls | awk '{print $7,$11}' | sort -nr | head |awk '{print $2}' | xargs ls -lh
-rw-r--r--. 1 root root 402K 2月 2 2013 /usr/share/doc/findutils-4.5.11/ChangeLog
-rw-r--r--. 1 root root 371K 4月 7 2018 /usr/share/doc/glib2-2.56.1/NEWS
-rw-r--r--. 1 root root 498K 5月 20 2022 /usr/share/doc/grub2-common-2.02/grub.html
-rw-r--r--. 1 root root 476K 9月 18 2012 /usr/share/doc/man-db-2.6.3/ChangeLog
-rw-r--r--. 1 root root 353K 3月 3 2012 /usr/share/doc/parted-3.1/ChangeLog
-rw-r--r--. 1 root root 709K 9月 5 2014 /usr/share/doc/rpm-4.11.3/ChangeLog.bz2
-rw-r--r--. 1 root root 575K 1月 10 2017 /usr/share/doc/rsyslog-8.24.0/ChangeLog
-rw-r--r--. 1 root root 404K 3月 12 2011 /usr/share/doc/tar-1.26/ChangeLog
-rw-r--r--. 1 root root 536K 9月 29 2015 /usr/share/doc/xz-5.2.2/ChangeLog
-rw-r--r--. 1 root root 510K 6月 29 2011 /usr/share/doc/yum-3.4.3/ChangeLog
awk 运算符
| 运算符 | 描述 |
|---|---|
| =、+=、-=、*=、/=、%=、^=、**= | **赋值运算符:**直接赋值、加赋值、减赋值、乘赋值、除赋值、求余赋值、求幂赋值 |
| +、-、*、/、%、^、 | **算数运算符:**加、减、乘、除、求余、求幂 |
| ++、– | **自增和自减运算符:**自增1、自减1,作为前缀或后缀 |
| +、- | **一元运算符:**一元加、一元减 |
| <、<=、>、>=、==、!= | **关系运算符:**小于、小于等于、大于、大于等于、等于、不等于 |
| ~、!~ | **正则表达式运算符:**匹配和不匹配 |
| &&、||、! | **逻辑运算符:**逻辑与、逻辑或、逻辑非 |
赋值运算符
[root@server ~ 19:22:48]# awk 'BEGIN { x=5;x+=2;print "x="x }'
x=7
[root@server ~ 19:23:03]# awk 'BEGIN { x=5;x-=2;print "x="x }'
x=3
[root@server ~ 19:23:09]# awk 'BEGIN { x=5;x*=2;print "x="x }'
x=10
[root@server ~ 19:23:13]# awk 'BEGIN { x=5;x/=2;print "x="x }'
x=2.5
[root@server ~ 19:23:17]# awk 'BEGIN { x=5;x%=2;print "x="x }'
x=1
[root@server ~ 19:23:21]# awk 'BEGIN { x=5;x^=2;print "x="x }'
x=25
[root@server ~ 19:23:25]# awk 'BEGIN { x=5;x**=2;print "x="x }'
x=25
算数运算符
[root@server ~ 19:24:08]# [root@server ~ 19:22:48]# awk 'BEGIN { x=5;x+=2;print "x="x }'
[root@server ~ 19:24:24]# x=7
[root@server ~ 19:24:24]# [root@server ~ 19:23:03]# awk 'BEGIN { x=5;x-=2;print "x="x }'
[root@server ~ 19:24:24]# x=3
[root@server ~ 19:24:24]# [root@server ~ 19:23:09]# awk 'BEGIN { x=5;x*=2;print "x="x }'
[root@server ~ 19:24:24]# x=10
[root@server ~ 19:24:24]# [root@server ~ 19:23:13]# awk 'BEGIN { x=5;x/=2;print "x="x }'
[root@server ~ 19:24:24]# x=2.5
[root@server ~ 19:24:24]# [root@server ~ 19:23:17]# awk 'BEGIN { x=5;x%=2;print "x="x }'
[root@server ~ 19:24:24]# x=1
[root@server ~ 19:24:24]# [root@server ~ 19:23:21]# awk 'BEGIN { x=5;x^=2;print "x="x }'
[root@server ~ 19:24:24]# x=25
[root@server ~ 19:24:24]# [root@server ~ 19:23:25]# awk 'BEGIN { x=5;x**=2;print "x="x }'
[root@server ~ 19:24:24]# x=25
更多推荐


所有评论(0)