Linux Sed

sed 用法

首先需要明确一点,sed不会改变源文件内容(除非使用 -i 参数或 w 行处理命令)

优秀博客:

https://www.cnblogs.com/maxincai/p/5146338.html https://www.cnblogs.com/BinBinStory/p/7282789.html

语法格式

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

常用参数(options)

  • -n 静默处理,仅显示处理后的结果,不加-n可能会出现重复打印的情况, eg: sed -n ‘/root/p’
  • -e 调用多个sed命令 eg: sed -e ‘10,20d’ -e ‘s/false/true/g’ 或用{} sed ‘{10,20d;s/false/true/g}’
  • -h 帮助
  • -i 直接对源文件进行改动

常用命令(command) command:行定位(正则) + sed 命令(操作)

行定位

  • 定位一行:
    • x
    • /pattern/
  • 定位几行:
    • x,y; /pattern/,x;
    • /pattern1/,/pattern2/;
    • x,y!
  • 定位间隔几行:
    • first~step
    • {n;p}, {n;n;p}

行处理命令

  • a 新增行(行尾新增)
  • i 插入行(行首插入)
  • c 替代行
  • d 删除行
  • s 替换字符串(分隔符/,#)
  • g 全局替换标志,配合s使用,假如不加g的话,每行只会替换匹配到的第一个字符串;加g,每行所有匹配到的字符串都替换
  • = 打印行号
  • & 代替之前匹配到的字符,常用在替换字符串, eg: sed ‘s/dzreal/&123/g’ test.txt 备注:&123 = dzreal123
  • () 替换某部分字符串(\1,\2)
  • 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]。

例子

#(1)输出一个log文件的300行到399行
sed -n '300,399p' access.log

#(2)删除空行
sed '/^$/d' test.txt

#(3)输出log日志里面的Error行
sed -n '/Error/p' php-error.log

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

#(5)输出基数行以及行号
sed -n '{1~2p;1~2=}' /etc/passwd

#(6)大小写转换,将passwd里面的姓名首字母变为大写
sed 's#^[a-z_-]\+#\u&#' /etc/passwd

#(7)把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

#(8)将123.txt文件插入到abc.txt的匹配行
sed '1r abc.txt' 123.txt    # 1代表abc.txt的第一行

#(9)将123.txt的1,2行插入到abc.txt当中
sed '1,2w abc.txt' 123.txt

#(10)清空一个文件全部内容
sed -i '1~1d' xxx.txt