第4章 sed命令和awk编程
- [1 sed命令基本用法](#1 sed命令基本用法)
-
- [1.1 sed命令位置](#1.1 sed命令位置)
- [1.2 sed适用的三种场合](#1.2 sed适用的三种场合)
- [1.3 sed三种命令格式](#1.3 sed三种命令格式)
- [1.4 sed命令选项及其意义](#1.4 sed命令选项及其意义)
- [1.5 sed 两种方式定位文本方法](#1.5 sed 两种方式定位文本方法)
- [2 sed编辑命令](#2 sed编辑命令)
- [3 sed 示例](#3 sed 示例)
-
- [3.1 -n参数](#3.1 -n参数)
- [3.2 多个参数同时执行(-e)](#3.2 多个参数同时执行(-e))
- [3.3 追加文本(-f)](#3.3 追加文本(-f))
- [4 sed 文本定位例子](#4 sed 文本定位例子)
-
- 4.1匹配元字符
- [4.2 匹配最后一行](#4.2 匹配最后一行)
- [4.3 匹配以字符结尾的字符串的行](#4.3 匹配以字符结尾的字符串的行)
- [4.4 取行区间之外(!)](#4.4 取行区间之外(!))
- [4.5 取行号到匹配行之间](#4.5 取行号到匹配行之间)
- [5 sed基本编辑命令举例](#5 sed基本编辑命令举例)
-
- [5.1 匹配行前面插入(i\)](#5.1 匹配行前面插入(i\))
- [5.2 替换匹配行(c\)](#5.2 替换匹配行(c\))
- [5.3 删除匹配行(d)](#5.3 删除匹配行(d))
- [5.4 替换文本(/s)](#5.4 替换文本(/s))
- [5.5 写新文件(/w)](#5.5 写新文件(/w))
- [5.6 从文件中读取(r)](#5.6 从文件中读取(r))
- [5.7 匹配到行退出(q)](#5.7 匹配到行退出(q))
- [5.8 变换命令](#5.8 变换命令)
- [5.9 显示控制字符](#5.9 显示控制字符)
- [5.10 在匹配行执行命令组](#5.10 在匹配行执行命令组)
- [6 sed 高级编辑命令示例](#6 sed 高级编辑命令示例)
-
- [6.1 处理匹配行的下一行(n)](#6.1 处理匹配行的下一行(n))
- [6.2 sed缓冲区处理](#6.2 sed缓冲区处理)
- [6.3 利用分号分隔多个编辑命令](#6.3 利用分号分隔多个编辑命令)
1 sed命令基本用法
1.1 sed命令位置
java
[root@localhost etc]# which sed
/bin/sed
[root@localhost etc]#
1.2 sed适用的三种场合
● 编辑相对交互式文本编辑器而言太大的文件。
● 编辑命令太复杂,在交互式文本编辑器中难以输入的情况。
● 对文件扫描一遍,但是需要执行多个编辑函数的情况。
1.3 sed三种命令格式
java
//1、在 Shell命令行输入命令调用sed, 格式为 :
sed [选项]'sed 命令:输入文件
--注意,需要用单引号将 sed 命令引起来。
//2、将 sed 命令插入脚本文件后,然后通过sed 命令调用它,格式为:
sed [选项]-f sed脚本文件输入文件
//3、将 sed 命令插入脚本文件后,最常用的方法是设置该脚本文件为可执行,然后直接执行该脚本文件,格式为:
./sed 脚本文件输入文件
1.4 sed命令选项及其意义
选 项 | 意 义 |
---|---|
-n | 不打印所有行到标准输出 |
-e | 表示将下一个字符串解析为sed编辑命令,如果只传递一个编辑命令给sed,-e选项可以省略 |
-f | 表示正在调用sed脚本文件 |
1.5 sed 两种方式定位文本方法
● 使用行号,指定一行,或指定行号范围。
● 使用正则表达式。
选 项 | 意 义 |
---|---|
X | x为指定行号 |
x,y | 指定从x到y的行号范围 |
/patterm/ | 查询包含模式的行 |
/pattern/pattern/ | 查询包含两个模式的行 |
/pattern/,x | 从与pattern的匹配行到x号行之间的行 |
x,/pattern/ | 从x号行到与pattern的匹配行之间的行 |
x,y! | 查询不包括x和y行号的行 |
2 sed编辑命令
选 项 | 意 义 |
---|---|
P | 打印匹配行 |
= | 打印文件行号 |
al | 在定位行号之后追加文本信息 |
il | 在定位行号之前插入文本信息 |
d | 删除定位行 |
cl | 用新文本替换定位文本 |
s | 使用替换模式替换相应模式 |
r | 从另一个文件中读文本 |
w | 将文本写入到一个文件 |
y | 变换字符 |
9 | 第一个模式匹配完成后退出 |
1 | 显示与八进制ASCⅡI码等价的控制字符 |
0 | 在定位行执行的命令组 |
n | 读取下一个输入行,用下一个命令处理新的行 |
h | 将模式缓冲区的文本复制到保持缓冲区 |
H | 将模式缓冲区的文本追加到保持缓冲区 |
x | 互换模式缓冲区和保持缓冲区的内容 |
g | 将保持缓冲区的内容复制到模式缓冲区 |
G | 将保持缓冲区的内容追加到模式缓冲区 |
3 sed 示例
3.1 -n参数
java
// -n只打印第一行
[root@localhost etc]# sed -n 1p passwd
root:x:0:0:root:/root:/bin/bash
//不加-n打印全部行
[root@localhost etc]# sed -n 1p passwd | wc -l
1
[root@localhost etc]# sed 1p passwd|wc -l
45
[root@localhost etc]#
//打印2-5行
[root@localhost etc]# sed -n "2,5p" passwd
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
//打印匹配行,匹配adm
[root@localhost etc]# sed -n "/adm/p" passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
[root@localhost etc]#
3.2 多个参数同时执行(-e)
java
[root@localhost etc]# sed -n "/nobody/=" passwd
13
30
[root@localhost etc]# sed -n -e "/nobody/p" -e "/nobody/=" passwd
nobody:x:99:99:Nobody:/:/sbin/nologin
13
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
30
[root@localhost etc]#
sed不支持同时带多个命令,如
java
[root@localhost etc]# sed -n "/nobody/p=" passwd
3.3 追加文本(-f)
java
[root@localhost etc]# sed '/rhel:/a\sed a new line.' /home/xj/test.log
tcpdump:x:72:72::/:/sbin/nologin
rhel:x:1000:1000:rhel:/home/rhel:/bin/bash
sed a new line. -- 新加的行
xj:x:808:809::/home/xj1:/bin/bash
//写一个sed追加文本的脚本
[root@localhost xj]# vi append.sed
#!/bin/sed -f
/rhel:/a\ #a\表示此处换行添加文本
We are family!.\ #"\"符号表示换行
We add a new line.
[root@localhost xj]# chmod +x append.sed
[root@localhost xj]# ./append.sed test.log
tcpdump:x:72:72::/:/sbin/nologin
rhel:x:1000:1000:rhel:/home/rhel:/bin/bash
We are family!. #新加的行
We add a new line. #新加的行
xj:x:808:809::/home/xj1:/bin/bash
4 sed 文本定位例子
4.1匹配元字符
java
[root@localhost xj]# sed -n '/\./p' test.log
.sdfaj
[root@localhost xj]# sed -n '/\$/p' test.log
$9999
4.2 匹配最后一行
java
[root@localhost xj]# sed -n '$p' test.log
last line!
[root@localhost xj]# sed -n '$'p test.log
last line!
4.3 匹配以字符结尾的字符串的行
匹配fix
java
[root@localhost xj]# sed -n '/.*fix/p' test.log
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
[root@localhost xj]#
4.4 取行区间之外(!)
java
[root@localhost xj]# sed -n '2,10!p' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
$9999
.sdfaj
last line!
[root@localhost xj]#
4.5 取行号到匹配行之间
java
[root@localhost xj]# sed -n '2,/ntp/p' test.log
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
[root@localhost xj]#
5 sed基本编辑命令举例
5.1 匹配行前面插入(i\)
java
[root@localhost xj]# cat append.sed
#!/bin/sed -f
/rhel:/i\
We are family!.\
We add a new line.
[root@localhost xj]# ./append.sed test.log
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
We are family!.
We add a new line.
rhel:x:1000:1000:rhel:/home/rhel:/bin/bash
[root@localhost xj]#
5.2 替换匹配行(c\)
java
[root@localhost xj]# cat append.sed
#!/bin/sed -f
/rhel:/c\
We are family!.\
We add a new line.
[root@localhost xj]# ./append.sed test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin
tcpdump:x:72:72::/:/sbin/nologin
We are family!.
We add a new line.
5.3 删除匹配行(d)
java
[root@localhost xj]# cat test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-
last line!
[root@localhost xj]# sed '1d' test.log
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-
last line!
[root@localhost xj]# sed '$d' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
[root@localhost xj]# sed '2,$d' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
//脚本(不区分大小写)
[root@localhost xj]# cat test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-
[root@localhost xj]# cat append.sed
#!/bin/sed -f
/[Ss][Ss][Hh][Dd]/d\
[root@localhost xj]# ./append.sed test.log
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-
5.4 替换文本(/s)
java
//将sshd替换为SSHD
[root@localhost xj]# sed "s/sshd/SSHD/" test.log
SSHD:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
// 添加参数/p
[root@localhost xj]# sed -n "s/sshd/SSHD/p" test.log
SSHD:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
// 添加/g将文本中全部sshd替换为SSHD
[root@localhost xj]# sed "s/sshd/SSHD/g" test.log
SSHD:x:74:74:Privilege-separated SSH:/var/empty/SSHD:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
// 替换第二次匹配
[root@localhost xj]# sed "s/sshd/SSHD/2p" test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/SSHD:/sbin/nologin
//将匹配行重定向
[root@localhost xj]# sed "s/sshd/SSHD/w 1.log" test.log
SSHD:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
[root@localhost xj]# cat 1.log
SSHD:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
//&符号
[root@localhost xj]# sed "s/sshd/(SSHD)/w 1.log" test.log
(SSHD):x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost xj]# sed "s/sshd/(&)/w 1.log" test.log
(sshd):x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost xj]#
5.5 写新文件(/w)
java
[root@localhost xj]# sed -n '/sshd/w 2.log' test.log
[root@localhost xj]# cat 2.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
[root@localhost xj]#
5.6 从文件中读取(r)
java
[root@localhost xj]# cat 2.log
add a new line from 2.log!
[root@localhost xj]# sed '/sshd/r 2.log' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
add a new line from 2.log!
5.7 匹配到行退出(q)
java
// 打印第一行后退出
[root@localhost xj]# sed '1 q' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
//匹配带h的行,匹配到第一个后退出
[root@localhost xj]# sed -n '/.h.*/p' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
[root@localhost xj]# sed '/.h.*/q' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
5.8 变换命令
sed y命令要求被变换的字符序列和变换的字符序列等长,否则 sed y命令将报错。
java
[root@localhost xj]# cat > 2.log
123
2356
143
^C
[root@localhost xj]# sed 'y/123/ABC/' 2.log
ABC
BC56
A4C
[root@localhost xj]#
5.9 显示控制字符
java
//注意$l中l为小写的字母l
[root@localhost xj]# sed -n '1,$l' 2.log
\033[17~\033[18~ \033[18~$
\033[15~$
\033OS$
5.10 在匹配行执行命令组
java
//显示匹配行和行号
[root@localhost xj]# sed -n '/sshd/{p;=}' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
1
[root@localhost xj]#
[root@localhost xj]# sed '/sshd/{s/h/H/;s/ss/88/}' test.log
88Hd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
6 sed 高级编辑命令示例
6.1 处理匹配行的下一行(n)
java
[root@localhost xj]# cat test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
[root@localhost xj]# sed '/sshd/{n;s/un/88/}' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/r88/avahi-daemon:/sbin/nologin
6.2 sed缓冲区处理
sed命令将输入文件复制到缓冲区,对缓冲区中的复制内容处理后,将其写入 输出文件。实际上,sed有两种缓冲区:模式缓冲区(Pattern Buffer)和保持缓冲区(Hold Buffer)。 前面提及的是模式缓冲区,而保持缓冲区是另一块内存空间, sed 的一些编辑命令可以对保 持缓冲区进行处理,并与模式缓冲区的内容互换。
java
[root@localhost xj]# cat test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
last line!
[root@localhost xj]# ^C
[root@localhost xj]# sed -e '/sshd/h' -e '/avahi/x' -e '$G' test.log
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
last line!
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
三个-e 选项带上三个编辑命令组成,第1个-e 选项后的编辑命令将 sshd关键字的匹配行写入保持缓冲区(h 命令指将模式缓冲区内容复制到保持缓冲区);第 2个-e 选项后的编辑命令是遇见 sshd关键字的匹配行时,将保持缓冲区中的内容输出,并 将 avahi关键字的匹配行写入保持缓冲区,因此,结果中,原本 avahi行的位置 变为了sshd行 (x 命令是互换模式缓冲区和保持缓冲区的文本内容);第3个-e 选项后的 编辑命令表示到最后一行时(用$符号匹配),将保持缓冲区的内容追加到模式缓冲区中 (G 命令的意义),因此结果中,最后一行是 avahi行。
h 和 H、g 和 G 是两组对应的命令, h 和 H 命令是模式缓冲区内容替换保持缓冲区内容,不过h 是副本,即将保持缓冲区的旧内容覆盖掉,而H 是追加,即在保持缓冲区旧内容上增加新的内容; g 和 G 命令是保持缓冲区内容替换模式缓冲区内容,同样, g 是副本、 G 是追 加。
6.3 利用分号分隔多个编辑命令
java
sed -e 's/s/S/' -e 's/m/M/' test.log
//等同于
sed 's/s/S/; s/m/M/' test.log
//二级命令提示符
[root@localhost xj]# sed '
> s/s/S/
> s/h/H/
> $d' test.log
SsHd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
avaHi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/Sbin/nologin
poStfix:x:89:89::/var/spool/postfix:/sbin/nologin
ntp:x:38:38::/etc/ntp:/Sbin/nologin
tcpdump:x:72:72::/:/Sbin/nologin
rHel:x:1000:1000:rhel:/home/rhel:/bin/baSh
db2inSt1:x:1001:901::/Home/db2inst1:/bin/bash
db2fenc1:x:1002:902::/Home/db2fenc1:/bin/baSh
db2aS:x:1003:903::/Home/db2as:/bin/bash
xj:x:808:809::/Home/xj1:/bin/baSh
$9999
.Sdfaj