SED
通常情况下我们是这样使用sed的:
sed OPTIONS... [SCRIPT] [INPUTFILE...]
OPTIONS可以说如下值[多个]
--help 帮助
--version 版本信息
-n --quiet --silent 默认情况下,完成一行的处理后,sed默认打印pattern space的内容,此选项将关闭默认打印。
-e SCRIPT --expression=SCRIPT 指定执行的命令,可以多次使用。当然,也可以用{}进行分组指定。
-f SCRIPT-file --file=SCRIPT-file 在文件中指定执行命令。
-i 直接修改输出到文件,儿不是到标准输出
在INFO手册,3.1节就描述了sed是怎么工作的。
sed 使用了两个数据缓存器 活动的 _pattern_ space, 辅助的 _hold_ space。其刚开始命令的时候都是空的。
sed以行为单位循环读入每行到 _pattern_space 执行命令,但是每行后面的换行符是不读入的,因此,在输出的时候会自动加上换行符。
处理完一行,通常(某些情况我们可以使他保留)是将_pattern_ space 清空,但并不清空 _hold_ space.
对于每一个命令,我们都可以给它指定执行的范围(某一行,或,某一范围)。
那么,我们应该注意到了两个关键之处:范围、命令
Selectiong lines with 'sed':
`number' 一个确切的数字,指定某行
`first~step' GNU SED扩展,first=起始 step=步长,想取奇数行就用 1~2,每五行就用 1~5.
`$' 最后一行
`/regexp/' 满足正则表达式的行[这并不在我们讨论的范围].如果正则表达式内包含'/',需要使用'\'进行转义。
`\%regexp%' 哈,为了避免上面那样的反引,你可以用任何一个符号来代替'%'。
`/regexp/I' `\%regexp%I' GNU 扩展,以大小写不敏感的方式来匹配正则式。
`/regexp/M' `\%regexp%M' GNU扩展 多行模式匹配正则式。这个时候'^'表示其前有一个换行,'$'表示其后跟随一个换行。
`ADDR1,+N' GNU 扩展,字面意义,很好理解。ADDR1及其后的N行。
`ADDR1,~N' GNU 扩展,找到ADDR1后的,继续匹配直到是N的倍数的行。注意与first~step区别,这条是匹配到了就不继续匹配了,而first-step是匹配到结束.
! GNU扩展,跟随在一个地址范围后,其意义是就是不匹配地址范围表达式的才会被选择。
Often-userd commands:
`# 注释
`q [EXIT-CODE] GNU扩展,只接受一个地址范围参数,打印当前 _pattern_ space 后退出,并返回退出码。
`d 删除当前 _pattern_ space,立即开始处理下一行。
`D 如果 _pattern_ space 没有换行符,等同于'd'命令。否则的话将 _pattern_ space 内容删除到第一个换行符为止,然后重新在_pattern_ space上执行命令,并不会读入下一行到_pattern_ space.
`p 打印当前 _pattern_ space 到标准输出,一般跟 -n选项配合使用
`P 打印 _pattern_ space 到出现第一个换行符的位置
`n 如果自动打印没有被-n关闭,此命令会打印当前 _pattern_ space 然后把_pattern_ space内的内容替换为下一行,如果没有输入了,就停止执行命令。
`N 给 _pattern_ space 添加一个换行符 同时将下一行的输入读进来。如果没有输入,不执行命令即退出。
`{COMMANDS } 一连串命令集合,以';'分割开的多条命令,在_pattern_ space上执行。
下面重点命令来了。
---------------
`s 替换命令。
命令原型:`s/REGEXP/REPLACEMENT/FLAGS'. '/'号同样可以用 其他符号代替,如:# % 等等避免'/'需要用转义
工作流程是:s 命令常用用REGEXP匹配 _pattern_ space 如果成功,就用REPLACEMENT替换。
REGEXP 可以用 '\(' '\)'进行分组,
在REPLACEMENT,可以用 \1..9 进行引用,&代表整个匹配的内容
在GNU扩展内 你还用一组'\'跟'L','l','U','u','E' 组成的序列。但这些并不常用。
`\L' 将REPLACEMENT变换为小写,直到 `\U' or `\E'出现。
`\l' 将REPLACEMENT中的下一个字符转变为小写.
`\U' 将REPLACEMENT变换为大写,直到 `\L' or `\E'出现。
`\u' 将REPLACEMENT中的下一个字符转变为大写.
`\E' 在REPLACEMENT中结束'\L','\U'的作用。
FLAGS:
`g 替换 _pattern_ space 内所有匹配的位置。不加此标志,只替换第一次匹配的位置
`NUMBER 替换 _pattern_ space 内第NUMBER匹配位置。(POSIX内并没有定义NUMBER 与g一起使用会是什么情况,GNU内,则表示从第NUMBER到最后一个匹配的位置)
`w FILENAME 如果s命令成功执行,将输出写到文件内。GNU扩展 支持使用'/dev/stdout /dev/stderr'
`e GNU 扩展。如果s命令执行成功,在 _pattern_ space找到的命令将会被执行,同时 _pattern_ space被替换为命令的输出
`p 打印出匹配后的 _pattern_ space。同时指定'ep' 或'pe' 效果是不一样的。pe将会打印找到的命令,而ep只是打印e的输出
`I,i GNU 扩展,以大小写不敏感的方式来匹配正则式。
`M,m GNU扩展 多行模式匹配正则式。这个时候'^'表示其前有一个换行,'$'表示其后跟随一个换行。
------------------------
`y/SOURCE_CHARS/DEST-CHARS/' 逐个替换为对应位置的字符比如 y/abc/ABC/ 凡 a被替换为A b替换为B
`a\TEXT 在当前循环输出后面加上TEXT。注意哦,是输出的后面,所以,如果你用-n命令关闭了打印的话,你就会发现怎么没效果了。可以使用转义字符。
GNU扩展一个属性,就是当啊 a与 TEXT中间,有'\t\r\n'这样的空白序列的时候,则忽略这些序列。对'i' 'c'命令同样如此
`i\TEXT 立刻打印TEXT
`c\TEXT 删除 _pattern_ space,打印 TEXT
`= 打印当前输入的是第几行,后面跟随一个换行符
`l N' 清晰的模式打印 _pattern_ space. 自己试试,中文全变成\232 \245这样的的了。行尾加上$
`r FILENAME 读取文件到当前循环的输出流后。文件名不存在也没事,就当读了个空。GNU扩展支持 /dev/stdin
`w FILENAME 将 _pattern_ space 写到文件.GNU扩展支持/dev/stderr /dev/stdout。文件将被创建(不存在)或被截短(已存在),在没有读入行之前。所有w 指令(包括s成功执行的w标志)不会关闭或者重新打开文件(提高效率)
`h 用 _pattern_ space 的内容替换 _hold_ space
`H 在 _hold_ space 后加一个换行符 同时把 _pattern_ space 的内容copy 过来
`g 用 _hold_ space 的内容替换 _pattern_ space的内容
`G 在 _pattern_ space 后加一个换行符 同时把 _hold_ space 的内容copy 过来
`x 交换 _pattern_ space 和 _hold_ space的内容
------------------
`: LABEL 设置个标签
`b LABEL 无条件跳往 LABEL标签。下一循环开始的时候,将会忽略这个标签
`t LABEL s成功执行后跳转到LABEL标签