sed

简介

行处理工具

语法格式

sed [options] 'command' file(s) # 命令行格式
sed [options] -f scriptfile file(s) # 脚本格式

常用参数(options)

  • -n 静默处理,仅显示处理后的结果,不加-n可能会出现重复打印的情况, eg: sed -n ‘/root/p’ filename

  • -e 调用多个sed命令 eg: sed -e ‘10,20d’ -e ‘s/false/true/g’ 或用{} sed '{10,20d;s/false/true/g}' filename

  • -h 帮助

  • -i 直接对源文件进行改动

  • -f 执行脚本

常用命令(command)

行定位

【定位一行】

sed -n '10p' file 打印第十行

【定位多行】

sed -n '1,100p' file 打印1到100行

【定位间隔行】

sed -n '1~3p' file 从第一行开始,每隔3行打印一次

行处理命令

  • a 新增行(在匹配行下方新增)

  • i 插入行(在匹配行上方新增)

  • c 替代行(替换匹配行)

  • d 删除行(删除选择的行)

  • s 替换字符串(分隔符/,#)

  • g 全局替换标志,配合s使用,假如不加g的话,每行只会替换匹配到的第一个字符串;加g,每行所有匹配到的字符串都替换

  • p 打印输出,一定要搭配 [-n] 参数使用,不然会出现莫名其妙的问题

  • = 打印行号

  • & 已匹配的字符串标记,eg: sed 's/dzreal/&93/g' file&对应着dzreal,命令意图是把dzreal替换成dzreal93

  • \( \) 替换某部分字符串,eg: s/\(dzreal\)93/\11993\1相当于dzreal,这个命令可看成是&的增强版

  • r 复制指定文件插入到匹配行(可以指定插入到b文件的哪一行后面,对源文件无更改)

  • w 复制匹配行拷贝指定文件里(直接对源文件进行更改)

  • q 退出sed

特殊元字符

\u # \l 首字母转化为大写\小写
\U # \L 整个字符串转化为大写\小写
\w # 匹配字母、数字、下划线,等价于’[A-Za-z0-9_]’。
\W # 匹配非字母、数字、下划线,等价于’[^A-Za-z0-9_]‘。
\s # 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。
\S # 匹配任何非空白字符,等价于[^\f\n\r\t\v]。
\d # 匹配一个数字字符。等价于[0-9]。
\D # 匹配一个非数字字符。等价于[^0-9]。
^ # 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ # 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. # 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* # 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] # 匹配一个指定范围内的字符,如/[ss]ed/匹配sed和Sed。
[^] # 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) # 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& # 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< # 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\> # 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} # 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} # 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} # 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。

例子

输出一个log文件的300行到399行

sed -n '300,399p' access.log
# 补充:打印奇偶数行
sed -n 'p;n' test.txt #奇数行
sed -n 'n;p' test.txt #偶数行

删除空行

sed '/^$/d' test.txt

输出log日志里面的Error行

sed -n '/Error/p' php-error.log

获取网卡中的ip

ifconfig | sed -n '/inet/p' | sed '{s/inet.*r://;s/[BM].*$//}' # 截断前部分和后部分的方法
ifconfig | sed -n '/inet/p' | sed 's/inet.*r:\([0-9.]\+\) .*$/\1/' # 直接取中间匹配的部分

输出基数行以及行号

sed -n '{1~2p;1~2=}' /etc/passwd

大小写转换,将passwd里面的姓名首字母变为大写

sed 's#^[a-z_-]\+#\u&#' /etc/passwd

把passwd里的user、uid、gid打印出来

sed 's#\(^[a-z_-]\+\):x:\([0-9]\+\):\([0-9]\+\):.*$#USER:\1 UID:\2 GID:\3#' /etc/passwd
# 用awk实现比较方便:
awk -F: '{print "USER:"$1, "UID:"$3, "GID:"$4}' OFS="\t" /etc/passwd

将123.txt文件插入到abc.txt的匹配行

sed '1r abc.txt' 123.txt # 1代表abc.txt的第一行

将123.txt的1,2行插入到abc.txt当中

sed '1,2w abc.txt' 123.txt

清空一个文件全部内容

sed -i '1~1d' xxx.txt