DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

sed notes


Synopsis

sed [options] [range]<command>[;[range]<command>] <target_file>

or:

command_for_sed_input_text | sed [options] [range]<command>

其中range可以是指定行,也可以是一个正则表达式(即所有符合表达式的行), 可以是开行前插入(i),在行后追加(a),替换行(c),在终端输出行(p)等等;

Options

  • -n: 不显示未处理行,见下面实例;

  • -i: "in-place" edit,见下面的实例;

删除文件中的空行

包括含几个空格、制表符的行:

sed -i '/^\s*$/d' target-file

显示文件的指定部分

例如一个200万行的文件名为error.log,需要从第587700行开始显示200行:

sed -n 587700,587900p error.log

解释:sed的p指令是将匹配到的行显示到终端上,-n是只显示选中的行, 所以使用p指令必加-n选项,-n后面的两个数字分别是起始和终止行号, 最后是要处理的文件名。所以显示文件myfile的第m到第n行的命令是:

sed -n m,np myfile

如果要显示的行是不连续的,需要用多个"-e"选项, 例如下面的命令打印input.txt文件的第1~10行,第53行和第200行:

sed -ne 1,10p -e 53p -e 200p input.txt

在文件的指定行前插入一行

在文件distro.txt第7行前插入一行"ab cd":

sed -i '7 i ab cd' distros.txt

"-i"表示结果写回原文件,而不是打印到stdout, 即"in-place" edit。同理,在第7行后加一行就是:

sed -i '7 a ab cd' distros.txt

把第7行替换为"ab cd":

sed '7 c ab cd' distros.txt

将多个编辑操作放在一个sed命令中进行

$ cat aaa
the first line
the 2nd line
last line

$ sed -e '1 a new line' -e '2 d' aaa
the first line
new line
last line

首先,多个操作用"-e"选项组合在一起,其次,每个操作中的行指的是原始文件的行, 而不是前面操作之后新的行,上面例子中第一个操作是在第一行后插入一行, 然后删掉第2行,可以看到删掉的是原文件的第2行,而不是新插入的行。

使用正则表达式处理多个行

$ sed '/.*line/ a abc' aaa the first line abc the 2nd line abc last line abc

输出指定区域的文本

有一个配置文件,现在想输出小节名称和后面的两行文本:

$ cat puppet.conf 
[main]
    The Puppet log directory.
    The default value is '$vardir/log'.
    logdir = /var/log/puppet
    Where Puppet PID files are kept.
    ...
[agent]
    The file in which puppetd stores a list of the classes
    associated with the retrieved configuratiion.  Can be loaded in
    the separate ``puppet`` executable using the ``--loadclasses``
    option.
    The default value is '$confdir/classes.txt'.
    classfile = $vardir/classes.txt
    ...

$ sed -n '/\[.*/,+2p' puppet.conf 
[main]
    The Puppet log directory.
    The default value is '$vardir/log'.
[agent]
    The file in which puppetd stores a list of the classes
    associated with the retrieved configuratiion.  Can be loaded in

这里使用了",+N"输出行及以后的N行文本这一模式。

文件末尾操作

sed的行号中,"$"代表最后一行,所以下面两句是等价的:

sed '$ a abcd' aaa
echo "abcd" >> aaa

但sed显然功能更强,比如可以用'$ i ...'实现在最后一行前面插入。

替换一行的指定部分

要把数据库地址改为mdb,也就是把mongodb://与:27017...之间的部分改成mdb, 方法是将要保留的部分放在正则表达式的group里, 替换的时候用backreference恢复要保留的部分, \1是前段,\2是后段,中间被替换的部分改为mdb:

$ cat default.json
{
  "db": {
    "address": "mongodb://dba:dba@192.168.100.3:27017/staging",
    "collection": "Schedule2"
  }
}
$ sed -i -r 's%(.*"address": "mongodb://).*(:27017.*)%\1mdb\2%' default.json
$ cat default.json
{
  "db": {
    "address": "mongodb://mdb:27017/staging",
    "collection": "Schedule2"
  }
}

由于文本中有/,所以sed的替换分隔符改成了%。 -i的作用是修改原文件,-r的作用是不需要为替换表达式中的括号转义。

参考:http://stackoverflow.com/questions/1074450/sed-replace-part-of-a-line



Published

Nov 8, 2011

Last Updated

Apr 21, 2020

Category

Tech

Tags

  • edit 1
  • range 1
  • sed 2
  • Unix 15

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor