sed,非交互式流编辑器

来源:互联网 发布:定时提醒的软件 编辑:程序博客网 时间:2024/06/04 17:57

语法:

    sed  [ -n ]  'command'  [ file ... ]

    sed  [ -n ]  -e  ‘command’ ...   [ file ... ]

    sed  [ -n ]  -f  script-file ...  [  file  ... ]


sed命令

 命令 功能 a\

 在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行

 c\ 用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行 i\ 在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行 d 删除行 h 把模式空间里的内容复制到暂存缓冲区 H 把模式空间里的内容追加到暂存缓冲区 g 把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容 G 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面 l 列出非打印字符 p 打印行 n 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理 q 结束或退出sed r 从文件中读取输入行 ! 对所选行以外的所有行应用命令 s 用一个字符串替换另一个 g 在行内进行全局替换   w 将所选的行写入文件 x 交换暂存缓冲区与模式空间的内容 y 将字符替换为另一字符(不能对正则表达式使用y命令)

 sed选项

 选项 功能 -e 进行多项编辑,即对输入行应用多条sed命令时使用 -n 取消默认的输出 -f 指定sed脚本的文件名
 
正则表达式元字符
 与grep一样,sed也支持特殊元字符,来进行模式查找、替换。不同的是,sed使用的正则表达式是括在斜杠线"/"之间的模式。
如果要把正则表达式分隔符"/"改为另一个字符,比如o,只要在这个字符前加一个反斜线,在字符后跟上正则表达式,再跟上这个字符即可。例如:sed -n '\o^Myop' datafile
 要匹配/,可以转义,\ /。匹配元字符,需转义
 元字符 功能 示例 ^ 行首定位符 /^my/  匹配所有以my开头的行 $ 行尾定位符 /my$/  匹配所有以my结尾的行 . 匹配除换行符以外的单个字符 /m..y/  匹配包含字母m,后跟两个任意字符,再跟字母y的行 * 匹配零个或多个前导字符 /my*/  匹配包含字母m,后跟零个或多个y字母的行 [] 匹配指定字符组内的任一字符 /[Mm]y/  匹配包含My或my的行 [^] 匹配不在指定字符组内的任一字符 /[^Mm]y/  匹配包含y,但y之前的那个字符不是M或m的行 \(..\) 保存已匹配的字符 1,20s/\(you\)self/\1r/  标记元字符之间的模式,并将其保存为标签1,之后可以使用\1来引用它。最多可以定义9个标签,从左边开始编号,最左边的是第一个。此例中,对第1到第20行进行处理,you被保存为标签1,如果发现youself,则替换为your。 & 保存查找串以便在替换串中引用 s/my/**&**/  符号&代表查找串。my将被替换为**my** \< 词首定位符 /\<my/  匹配包含以my开头的单词的行 \> 词尾定位符 /my\>/  匹配包含以my结尾的单词的行 x\{m\} 连续m个x /9\{5\}/ 匹配包含连续5个9的行 x\{m,\} 至少m个x /9\{5,\}/  匹配包含至少连续5个9的行 x\{m,n\} 至少m个,但不超过n个x /9\{5,7\}/  匹配包含连续5到7个9的行


s命令里以g结尾表示:替代文本取代正则表达式中的每一个匹配的。如果没有设置g,sed就会取代第一个匹配的。

鲜为人知的是:你可以在结尾指定数字,指示第n个匹配出现才要被取代:

$echo  Tolstoy  reads well. Tolstoy  writes well.  > example.txt

$sed  's/Tolstoy/Camus/2'   < example.txt

Tolstoy  reads  well.  Camus writes well.


POSIX允许使用分号将同一行里的不同命令隔开:

sed  's/foo/bar/g ; s/chicken/cow/g'  myfile  > myfile2

不过许多商用sed版本可能不支持此用法。


ed与其先驱ex和vi一样,sed会记得在脚本里遇到的最后一个正则表达式——不管它在哪里。

s/foo/bar/3                   替换第三个foo

s//quux/                        替换第一个foo



sed运行方式:

sed读取每一个文件,一次读一行,将读取的行放在内存的一个区域——称之为模式空间(pattern space)。这就像程序语言里的变量一样:内存的一个区域在编辑命令的指示下可以修改,所有编辑上的操作都会应用到模式空间的内容。当所有操作完成后,sed会将模式空间的最后内容打印到标准输出,再回到开始处,读取另一个输入行。


匹配特定行:

sed默认是将每一个编辑命令用用到每一个输入行。但是,其实它是可以定值的。即,限制一条命令要用到那些行,只要在命令前置一个地址即可。所以sed 命令的完成形式就是:

address  command

以下为不同种类的地址:

正则表达式

    将以模式放置到一条命令之前,可限制命令应用于匹配模式的行。可与s命令搭配使用:

    /oldfunc/   s/$/#  XXX: migrate  to  newfunc/

    s命令里的空模式指的是“使用前一个正则表达式”

行编号

   可以使用绝对的行编号作为地址。

   sed  10q  foo     q命令要求sed马上结束,这个命令可以打印foo的开头10行

最终行

  符号$(就像在ed与ex里一样)指“最后一行”。下面的脚本指的就是快速打印文件最后一行。

    sed  -n  '$p'   "$1"

   对sed而言,即便是处理多个人间,sed也将它们视为一个长的输入流,而$只应用到最后一个文件的最后一行(GNU的sed具有一个选项,可是地址分开地应用到每个文件)

范围

    可指定行的范围,将地址以逗号隔开:

   sed  -n  '10,42p'   foo                              打印10~42行

    sed  '/foo/,/bar/   s/baz/quux/g'                        仅替换范围内的行,从含有foo的行开始,在第一个匹配到的bar

否定正则表达式

   /used/!  s/new/used/g                        将没有used的每个行里所有的new改成used

    POSIX标准明确指出:空白跟随!之后的行为是“未定义的”。


有多少文本会改动?

不想使用grep查找,你只要看看哪一行是什么就够了。sed进行文本替换,所以你要了解,究竟会替换确切的是多少字符。

从最左边开始,扩展至最长:正则表达式匹配可以匹配整个表达式的输入文本中最长的,最左边的子字符串。除此之外,匹配的空(null)字符串,则被认为是比完全不匹配的还长。(例如:ab*c匹配到ac,则b*成功匹配到ac之间的null)。

$echo  Tolstoy  is worldy  |  sed  's/T.*/Camus/'

Camus

这里只是想要匹配Tolstoy,但由于匹配会扩展到可能的最长长度的文本量,所有就到了worildy的y处。可以这样修改

$echo  Tolstoy  is  worldly  |  sed  's/T[[:alpha:]]*y/Camus/'

Camus  is  worldly


举个匹配null的例子:

$echo  abc  |  sed 's/b*/1/'               替换第一个匹配成功的

1abc

$echo  abc  | sed  's/b*/1/g'             替换所有匹配成功的

1a1c1

请留意,b*是如何匹配到abc的前面和结尾的null字符

原创粉丝点击