Chapter4 sed替换命令详解
sed的替换命令是最常用的,也是讲解最多的。
sed的模式空间
sed的基本工作方式是:
将文件以行为单位读取到内存(模式空间)
使用sed的每个脚本对该行进行操作
处理完成后输出该行
替换命令s
sed的替换命令s:
sed 's/old/new/' filename
sed -e 's/old/new/' -e 's/old/new/' filename
sed -i 's/old/new/' 's/old/new/' filename
带正则表达式的替换命令s
sed 's/正则表达式/new/'filename
举例:
echo a a a > afile
sed 's/a/aa/' afile #只替换了第一个a,!也可以做分隔符
sed -e 's/a/aa/' -e 's/aa/bb/' afile
也可以简写为
sed 's/a/aa/;s/aa/bb/' afile
#使用-i写入原始文件
sed -i 's/a/aa/ ;s/aa/bb/' afile
#将三个字符串替换为空
head -5 /etc/passwd | sed 's/...//'
#s出现了1次或0次,只会替换第一次匹配的
head -5 /etc/passwd | sed 's/s*bin//'
grep root /etc/passwd | sed 's/^root//'
sed -r 's/扩展正则表达式/new/' filename
举例:
cat bfile
b
a
aa
aaa
ab
abb
abbb
sed 's/ab*/!/' bfile
sed -r 's/ab+/!/' bfile #+是扩展元字符,所以要加 -r
sed -r 's/ab?/!/' bfile
sed -r 's/(aa)|(bb)/!/' bfile #()是sed独有的,算在扩展元字符里面
#使用sed里面圆括号的回调功能,\1作为分组
cat cfile
axyzb
sed -r 's/(a.*b)/\1:\1/' cfile
Chapter5 sed替换命令加强版
全局替换
s/old/new/g
g为全局替换,用于替换所有出现的次数。
/ 如果和正则匹配的内容冲突可以使用其他符号,如:s@old@new@g
head -5 /etc/passwd | sed 's/root/!!!!/g'
#只对第二次出现的匹配进行替换,其他的只进行匹配而不替换
head -5 /etc/passwd | sed 's/root/!!!!/2'
标志位
数字
,第几次出现才进行替换
g
每次出现都进行替换
p
打印模式空间的内容(即输出两次,一次是sed的标准输出,二是完成后的输出)
sed -n 'script' filename
阻止默认输出
#sed的工作模式是匹配一行输出一行,而使用-n选项阻止默认输出,与p联用则只打印出替换成功的内容
head -5 /etc/passwd | sed -n's/root/!!!!/p'
w file
将模式空间的内容写入到文件
head -5 /etc/passwd | sed -n 's/root/!!!!/w /tmp/a.txt'
寻址
默认对每行进行操作,增加寻址后对匹配的行进行操作。
/正则表达式/s/old/new/g
行号s/old/new/g
行号可以是具体的行,也可以是最后一行 $ 符号
可以使用两个寻址符号,也可以混合使用行号和正则地址
#限制第一行执行
head -6 /etc/passwd | sed '1s/bin/!/'
#限制1-3行执行
head -6 /etc/passwd | sed '1,3s/bin/!/'
#限制1到最后一行执行
head -6 /etc/passwd | sed '1,$s/bin/!/'
#使用正则表达式(root这一行)限制
head -6 /etc/passwd | sed '/root/s/bash/!/'
#行号与正则表达式的混用(以bin开头到最后一行的范围)
head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/'
分组
寻址可以匹配多条命令,;
连接
/regular/{s/old/new/;s/old/new}
sed脚本文件
可以将选项保存为文件,使用-f
加载脚本文件
sed -f sedscript filename
Chapter 6 sed的其他常用指令
删除命令
[寻址]d
删除模式空间内容,并不是原文件的内容,改变脚本的控制流,读取新的输入行。
sed '/ab/d' bfile #删除匹配到字符的一整行,与替换不同
sed '/ab/d;s/a/!/' bfile #一般是先进行替换命令,在进行删除命令,不然删除命令会改变文件原有结构
追加、插入、更改
追加命令a
插入命令i
更改命令c
#在字符ab的后面添加"hello"
sed '/ab/a hello' bfile
#匹配后直接改写字符串
sed '/ab/c hello' bfile
打印
打印命令p
下一行
下一行命令n
打印行号命令=
读文件和写文件
读文件命令r
写文件命令w
#r选项将afile的内容读取到bfile的ab字符串后面,从而完成俩文件的合并
sed '/ab/r afile' bfile
退出命令
退出命令q
哪个效率更高呢?
#前者更快
sed 10q filename #只到第十行就停止
sed -n 1,10p filename #所有行都被会读入内存,但只打印出前十行
seq 1 1000000 > lines.txt
Chapter7 sed多行模式空间
sed的多行模式
多行模式处理命令N,D,P
N
将下一行加入到模式空间
vim a.txt
hel
lo
sed 'N;s/hel\nlo/!!!/' a.txt #行与行之间通过换行符\n来连接
sed 'N;s/hel.lo/!!!/' a.txt
D
删除模式空间中的第一个字符到第一个换行符
cat > b.txt << EOF
hell
o bash hel
lo bash
EOF
sed 'N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt #其实是用N将1、2行联系起来,将hello bash替换成hello sed,然后打印出来,再删除模式空间第一个字符到第一个换行符。
P
打印模式空间中的第一个字符到第一个换行符
配置文件一般为单行出现
也有使用XML或JSON格式的配置文件,为多行出现。
Chapter8 什么是sed的保持空间
保持空间也是多行的一种操作方式。
将内容暂存在保持空间,便于做多行处理。
h
和H
将模式空间内容存放到保持空间(小写是覆盖模式,大写是追加模式)
g
和G
将保持空间内容取出到模式空间(小写是覆盖模式,大写是追加模式)
x
交换模式空间和保持空间内容
#将文件内容的前六行进行倒序排列
cat -n /etc/passwd | head -6 | sed -n '1h;1!G;$!x;$p' #第一行取出到保持空间,不让保持空间的第一行取出到模式空间,不让模式空间最后一行交换,输出最后一行
#精简1
cat -n /etc/passwd | head -6 | sed -n 'G;h;$p' #如果不加$p的话,输出内容会有很多
#精简2,去掉第一行的换行符
cat -n /etc/passwd | head -6 | sed -n '1!G;h;$p'
#再精简
cat -n /etc/passwd | head -6 | sed -n '1!G;h;$!d'
附练习题(来源于https://blog.csdn.net/y1412813204/article/details/86701837
):
测试文件
Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln , NB 92743:7/25/53:85100
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
Barbara Kertz:385-573-8326:832 Ponce Drive, Gzary, IN 83756:12/1/46:268500
Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900
将以上文本命名为Week41.config
以下有九个练习题(附答案)
1.把Jon的名字改为Jonathan
2.删除头3行
3.打印第5~10行
- 删除含有Lane的所有行
- 打印所有生日在十一月或十二月的行
- 在以Kare开头的行末尾加上3颗星
- 将所有包含Jose的行都替换为JOSE HAS RETIRED
- 删除所有空行
答案
1.sed 's/Jon/Jonathan/' Week41.config | grep Jonathan
2.sed '1,3'd Week41.config | less -SN
3.sed -n '5,10'p Week41.config
4.sed '/Lane/'d Week41.config | grep Lane
5.sed -n '/:1[1,2]\//'p Week41.config
6.sed '/^Kare/ s/$/ ***/' Week41.config #至于为什么不用管道府和分号目前还不晓得
7.sed 's/Jose/JOSE/g' Week41.config | grep JOSE
8. sed -r '/^[[:space:]]*(#|$)/d' Week41.config | less -SN
#也可以简写为
sed -r '/^\s*$/d' Week41.config | less -SN #个人感觉#在这里用处不大
网友评论