1.定位行
sed命令用来处理文本,在处理前首先要找得到待处理的行,这是逻辑上必须的。所以需要首先定位,然后对定位到的各行进行各种处理,包括插入,删除,替换等。
sed -n '10p' testfile // sed命令默认会打印出经过处理后所有的文本,-n选项则不打印这种默认文本。10为要定位的行,找到之后执行p命令,打印这一行。
sed -n '1,10p' testfile // 打印1-10行。
sed -n '2,$p' testfile // 打印第二行到最后一行。
sed -n '3~2p' testfile // 打印第3,5,7,9,…….行,你懂得。
sed -n '/Barry/,10p' testfile // 首先找到第一个匹配/Barry/(可以是其他基本正则表达式)的行,打印从这一行到第10行。
sed -n '1,3!p' testfile // 打印1-3行以外的行("!"的作用)。
sed -n '1{n;p}' testfile // 首先定位到第一行,然后执行命令n,定位到第一行的下一行,然后执行p打印,可见定位之后可以用 {}执行命令组合。
sed -n 'p' testfile // 什么都不写,则定位全部的行。
采用a,b这种模式定位时,首先定位a(如果超出范围或者未找到,就不会去查找b),然后定位b,如果b这一行在a的上面会出现什么状况呢?例如:
sed -n '/Barry/,/Hello/p' testfile
该首先会定位到/Barry/,如果/Hello/这一行在/Barry/这一行上面,则只打印/Barry/这一行。为什么会这样?原来,sed定位是不回退的,即找到了/Barry/这一行之后,就从这一行下面找/Hello/,当然找不到了,所以只打印了/Barry/这一行。
2.命令
在定位之后当然是执行指定的命令了。看实例:
sed '1,3d' testfile // 删除1-3行,打印剩余的文本,注意,此时文件本身并没有改变。d命令是删除命令。
sed -n '5,10a helloworld' testfile // 在5-10行每一行后面都增加一行 helloworld。a命令在行后插入一行。
sed -n '5,10i helloworld' testfile // 在5-10行每一行前面都增加一行 helloworld。i命令在行前插入一行。
sed -n ‘5~3c helloworld’ testfile //把5,8,11,14,17,20,23,26……依次替换为helloworld。c命令替换行。
sed -n '5,10c helloworld' testfile // 把5-10行整体替换成一行helloworld。当替换目标是连续的行时,把整体替换成一行。
sed -n -r '5,10s/yes|Yes/no/gp' testfile // 5-10行的yes或者Yes被替换成no。 -r 选项使sed支持扩展正则表达式。
s命令是替换命令,通常格式是line1,line2s/字符串1/字符串2/g,即把line1~line2的字符串1全部用字符串2代替,字符串1可以是正则表达式。这里不再对正则表达式详细介绍。如果末尾不加g字符,则表示只替换每行的第一个匹配的字符串。
sed '1,10s/$/helloworld/' testfile // 在1~10行中,替换每行的行尾设置为helloworld。$是正则表达式的行尾标志。
sed '5,10y/abc/ABC/' testfile // 5-10行的a被换成A,b被换成B,c被换成C,类似tr命令的功能。y命令替换以字符为单位,而s命令以字符串为单位。
sed '/My/r textfile' testfile // r命令是读命令,sed使用该命令将一个文本文件中的内容加到当前行的下面。
sed -n '1,10w newfile' testfile // 将1-10行写入newfile。w命令可以将指定的行写入指定的文件。
sed -n '/root/{=;p}' testfile // 定位到/root/行之后,打印行号,然后打印这一行。"="是打印行号的命令。
3.特殊选项
sed -i '1,10d' testfile // 直接在文件中删除1~10行。-i选项表示对真实文件进行操作,所做的更改将保存到文件中。
sed -s '1d' testfile1 testfile2 testfile3 // 此处有三个文件,如果不加-s,则将三个文件读入,当作一个整体处理,-s选项使分别处理。
sed -e '/root/p' -e '/Barry/d' testfile // 此处用-e选项可以进行多次处理,第一次打印/root/行,第二次删除/Barry/行。
sed -e '/root/{n;p}' -e '/Barry/{n;d}' testfile // 每次处理时,可以对每次匹配到的行执行多个命令。命令之间用";"分隔。