Linux中sed文本处理工具原理及使用

Sed是什么?

Sed是一种非交互式的流编辑器,可动态编辑文件;流编辑器则会在编辑器处理数据之前基于预先提供的一组 规则来编辑数据流

Sed本身是一个管道命令,可以分析 standard input 的,主要是用来分析关键字的使用、统计等,此外还可 以将数据进行替换、删除、选中、选取特定行等功能

Sed主要用来自动编辑一个或多个文件,可以将数据行进行替换、删除、新增、选取等特定工作,简化对文件 的反复操作,编写转换程序等

sed参数 作用
-e 直接在命令行模式上进行sed动作编辑,此为默认选项;
-f 将sed的动作写在一个文件内,用–f filename 执行filename内的sed动作;
-i 直接修改文件内容;
-n 只打印模式匹配的行;
-r 支持扩展表达式;
-h或–help 显示帮助;
-V或–version 显示版本信息

常用命令:

元字符 功能
a\ 在当前行下面插入文本;
i\ 在当前行上面插入文本;
c\ 把选定的行改为新的文本;
d 删除,删除选择的行;
D 删除模板块的第一行;
s 替换指定字符;
h 拷贝模板块的内容到内存中的缓冲区;
H 追加模板块的内容到内存中的缓冲区;
g 获得内存缓冲区的内容,并替代当前模板块中的文本;
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面;
l 列表不能打印字符的清单;
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令;
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码;
p 打印模板块的行。 P(大写) 打印模板块的第一行;
q 退出Sed;
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾;
r file 从file中读行;
t label if分支,从后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本 的末尾;
T label 错误分支,从后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾;
w file 写并追加模板块到file末尾;
W file 写并追加模板块的第一行到file末尾;
! 表示后面的命令对所有没有被选定的行发生作用;
= 打印当前行号;
# 把注释扩展到下一个换行符以前;
/g 表示行内全面替换;
/p 表示打印行;
/w 表示把行写入一个文件;
/x 表示互换模板块中的文本和缓冲区中的文本;
/y 表示把一个字符翻译为另外的字符(但是不用于正则表达式);
\1 子串匹配标记;
& 已匹配字符串标记;
元字符 功能
^ 行首定位符
$ 行尾定位符
. 匹配除换行符以外的单个字符
* 匹配零个或多个前导字符
? 匹配零个或1个前导字符
+ 匹配1个或多个前导字符
| 或操作
\s 匹配单个空白字符(如\t)
\S 匹配单个非空白字符
\w 匹配单个单词
\W 匹配单个非单词
[] 匹配指定字符组内的任一字符
[^] 匹配不在指定字符组内的任一字符
[-] 匹配字符集的字符范围
(..) 保存已匹配的字符(括号前面要加反斜杠\,csdn没显示出来)
& 保存查找串以便在替换串中引用
< 词首定位符
> 词尾定位符
x{m} 连续m个x
x{m,} 至少连续m个x
x{m,n} 至少连续m个,但不超过n个x
(str) 正则表达式中对字符串的引用(括号前面要加反斜杠\,csdn没显示出来)
中括号表达式 如[:alnum:],[:alpha:],[:digit:],[:lower:],[:upper:],[:punct:],[:space:]

#替换操作:s
sed ‘s/book/books/’ file
sed -n ‘s/test/TEST/p’ file #-n选项和p命令一起使用表示只打印那些发生替换的行
sed -i ‘s/book/books/g’ file #编辑文件选项-i,会匹配file文件中每一行的第一个book替换为books

#全局替换:g
sed ‘s/book/books/g’ file #/g 标记会替换每一行中的所有匹配
echo sksksksksksk | sed ‘s/sk/SK/2g’ #需要从第N处匹配开始替换时,可以使用 /Ng
echo sksksksksksk | sed ‘s/sk/SK/3g’
echo sksksksksksk | sed ‘s/sk/SK/4g’

#定界符
#以上命令中字符 / 在sed中作为定界符使用,也可以使用任意的定界符
sed ‘s:test:TEXT:g’

sed ‘s|test|TEXT|g’
#定界符出现在样式内部时,需要进行转义:
sed ‘s//bin//usr/local/bin/g’

#删除:d
sed ‘/^$/d’ file #删除空白行
sed ‘2d’ file
sed ‘2,$d’ file
sed ‘$d’ file
sed '/^test/'d file

#已匹配字符串标记&
#正则表达式 \w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词
echo “this is a test line” | sed ‘s/\w+/[&]/g’
#所有以192.168.0.1开头的行都会被替换成它自已加localhost:
sed ‘s/^192.168.0.1/&localhost/’ file

#子串匹配标记\1
echo this is digit 7 in a number | sed ‘s/digit ([0-9])/\1/’
#命令中 digit 7,被替换成了 7。样式匹配到的子串是 7,(…) 用于匹配子串,对于匹配到的第一个子串就 标记为 \1,依此类推匹配到的第二个结果就是 \2
echo aaa BBB | sed ‘s/([a-z]+) ([A-Z]+)/\2 \1/’
#love被标记为1,所有loveable会被替换成lovers,并打印出来
sed -n ‘s/(love)able/\1rs/p’ file

#组合多个表达式
sed ‘表达式’ | sed ‘表达式’
sed ‘表达式; 表达式’

#引用
#sed表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号
test=hello
echo hello WORLD | sed “s/$test/HELLO”

#选定行的范围:,(逗号)
#所有在模板test和check所确定的范围内的行都被打印
sed -n ‘/test/,/check/p’ file
#打印从第5行开始到第一个包含以test开始的行之间的所有行:
sed -n ‘5,/^test/p’ file
#对于模板test和west之间的行,每行的末尾用字符串aaa bbb替换
sed ‘/test/,/west/s/$/aaa bbb/’ file

#多点编辑,e
#-e选项允许在同一行里执行多条命令
sed -e ‘1,5d’ -e ‘s/test/check/’ file
#上面sed表达式的第一条命令删除1至5行,第二条命令用check替换test。命令的执行顺序对结果有影响。如果两 个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果

#从文件读入:r
#file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面
sed ‘/test/r file’ filename

#写入文件:w
#在example中所有包含test的行都被写入file里
sed -n ‘/test/w file’ example

#追加(行下):a
#将 this is a test line 追加到 以test 开头的行后面
sed ‘/^test/a\this is a test line’ file
sed -i ‘2a\this is a test line’ test.conf #第2行之后插入

#插入(行上)
#i\命令 将 this is a test line 追加到以test开头的行前面
sed ‘/^test/i\this is a test line’ file
sed -i ‘5i\this is a test line’ test.conf

#下一个:n #如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续 sed ‘/test/{ n; s/aa/bb/; }’ file

#转换:y
#把1~10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令
sed ‘1,10y/abcde/ABCDE/’ file

#只显示IP地址
ifconfig
ifconfig | egrep ‘inet’
ifconfig | egrep inet | grep -v inet6 | sed ‘s/^.inet//g’ | sed 's/netmask.$//g’

#去掉ssh配置文件中的带#行和空行
more /etc/ssh/sshd_config
more /etc/ssh/sshd_config | sed ‘s/#.*KaTeX parse error: Expected 'EOF', got '#' at position 42: …onfig | sed 's/#̲.*//g’ | sed '/^$/d


将/etc/passwd文件拷贝一份,做以下练习:
1.删除文件每行的第一个字符

[root@linux ~]# sed -n 's/^.//p' passwd | tail -3
yquota4:x:10014:10025::/app/home/myquota4:/bin/bash
yquota5:x:10015:10025::/app/home/myquota5:/bin/bash
pache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

2.删除文件每行的第二个字符

[root@linux ~]# sed -r 's/^(.)(.)/\1/g' passwd | tail -3
mquota4:x:10014:10025::/app/home/myquota4:/bin/bash
mquota5:x:10015:10025::/app/home/myquota5:/bin/bash
aache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

3.删除文件每行的最后一个字符

[root@linux ~]# sed -r 's/(.)(.)$/\1/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bas
myquota5:x:10015:10025::/app/home/myquota5:/bin/bas
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologi

4.删除文件每行的倒数第二个字符

[root@linux ~]# sed -r 's/(.)(.)$/\2/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bah
myquota5:x:10015:10025::/app/home/myquota5:/bin/bah
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologn

5.删除文件每行的第二个单词

[root@linux ~]# sed -r 's/(^[^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)/\1\2\3/' passwd | tail -3
myquota4::10014:10025::/app/home/myquota4:/bin/bash
myquota5::10015:10025::/app/home/myquota5:/bin/bash
apache::48:48:Apache:/usr/share/httpd:/sbin/nologin

6.删除文件每行的倒数第二个单词

[root@linux ~]# sed -r 's/([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)$/\2\3\4/' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4://bash
myquota5:x:10015:10025::/app/home/myquota5://bash
apache:x:48:48:Apache:/usr/share/httpd://nologin

7.删除文件每行的最后一个单词

[root@linux ~]# sed -r 's/([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)$/\1\2\4/' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/
myquota5:x:10015:10025::/app/home/myquota5:/bin/
apache:x:48:48:Apache:/usr/share/httpd:/sbin/

8.交换每行的第一个字符和第二个字符

[root@linux ~]# sed -r 's/^(.)(.)/\2\1/g' passwd | tail -3
ymquota4:x:10014:10025::/app/home/myquota4:/bin/bash
ymquota5:x:10015:10025::/app/home/myquota5:/bin/bash
paache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

9.交换每行的第一个字符和第二个单词

[root@linux ~]# sed -r 's/(^[^a-Z]*)(.)([a-Z]+)([^a-Z]+)([a-Z]+)/\1\5\3\4\2/g' passwd | tail -3
xyquota4:m:10014:10025::/app/home/myquota4:/bin/bash
xyquota5:m:10015:10025::/app/home/myquota5:/bin/bash
xpache:a:48:48:Apache:/usr/share/httpd:/sbin/nologin

10.交换每行的第一个单词和最后一个单词

[root@linux ~]# sed -r 's/(^[^a-Z]*)([a-Z]+)([^a-Z]+)(.*)([^a-Z]+)([a-Z]+)([^a-Z]*$)/\1\6\3\4\5\2\7/' passwd | tail -3
bash4:x:10014:10025::/app/home/myquota4:/bin/myquota
bash5:x:10015:10025::/app/home/myquota5:/bin/myquota
nologin:x:48:48:Apache:/usr/share/httpd:/sbin/apache

11.删除一个文件中所有的数字

[root@linux ~]# sed -r 's/[0-9]*//gp' passwd | tail -3
myquota:x::::/app/home/myquota:/bin/bash
apache:x:::Apache:/usr/share/httpd:/sbin/nologin
apache:x:::Apache:/usr/share/httpd:/sbin/nologin

12.删除每行开头的所有空格

[root@linux ~]# sed -r 's/^[[:space:]]//g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

13.用制表符替换文件中出现的所有空格

[root@linux ~]# sed -r 's/[[:space:]]/\t/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

14.把所有大写字母用括号()括起来

[root@linux ~]# sed -r 's/[A-Z]/\(&\)/g' passwd | tail -3
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:(A)pache:/usr/share/httpd:/sbin/nologin

15.打印每行3次

[root@linux ~]# sed 'p;p' passwd | tail -6
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

16.隔行删除

[root@linux ~]# sed  '0~2 {=;d}' passwd | tail -5
30
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
32
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
34

17.把文件从第12行到第23行复制到第32行后面

[root@linux ~]# sed  '12h;13,23H;32G' 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:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
david:x:10007:10012::/home/david:/bin/bash
peter:x:10008:10012::/home/peter:/bin/bash
jack:x:10009:10013::/home/jack:/bin/bash
mike:x:10010:10013::/home/mike:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
myquota1:x:10011:10025::/app/home/myquota1:/bin/bash
myquota2:x:10012:10025::/app/home/myquota2:/bin/bash
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
myquota4:x:10014:10025::/app/home/myquota4:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

18.把文件从第12行到第23行移动到第32行后面

[root@linux ~]# sed  '12{h;d};13,23{H;d};32g' 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:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
david:x:10007:10012::/home/david:/bin/bash
peter:x:10008:10012::/home/peter:/bin/bash
jack:x:10009:10013::/home/jack:/bin/bash
mike:x:10010:10013::/home/mike:/bin/bash
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
myquota1:x:10011:10025::/app/home/myquota1:/bin/bash
myquota2:x:10012:10025::/app/home/myquota2:/bin/bash
myquota3:x:10013:10025::/app/home/myquota3:/bin/bash
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
student:x:1007:1007::/home/student:/bin/bash
harry:x:1012:1012::/home/harry:/bin/bash
alice:x:10005:10008::/home/alice:/bin/bash
jack.willianmus:x:10006:10006::/home/jack:/bin/bash
myquota5:x:10015:10025::/app/home/myquota5:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

19.只显示每行的第一个单词

[root@linux ~]# sed 's/\([a-Z]\+\)\([^a-Z]\+\)\(.*\)/\1/' /etc/passwd | tail -3  
myquota
myquota
apache

20.打印每行的第一个单词和第三个单词

[root@linux ~]# sed 's/\([a-Z]\+\)\([^a-Z]\+\)\([a-Z]\+\)\([^a-Z]\+\)\([a-Z]\+\)\([^a-Z]\+\)\(.*\)/\1\t\5/' /etc/passwd | tail -3  
myquota app
myquota app
apache  Apache

21.将格式为 mm/yy/dd 的日期格式换成 mm;yy;dd

[root@linux ~]# date '+%m/%y/%d' |sed 's#/#; #g'
10; 18; 31

猜你喜欢

转载自blog.csdn.net/QQ1006207580/article/details/83588691