sed 手册阅读笔记<转>

原文链接
sed 手册阅读笔记 摘要 sed 手册本身不太适合初学者,我在看的过程中加了一些 自己的注释和一些例子,帮助理解,如有偏差或错误,请指出,多谢。 目录 1. sed的工作原理 2. sed中如何选择特定的行 3. sed的命令行选项 4. sed命令 1. sed的工作原理 sed维护两个缓冲区,pattern space和 hold space,命令开始执行之前都为空。 pattern space缓冲区用于临时保存每次读取的一行的内容,大部分的 匹配和替换等等操作都是针对pattern space中的内容进行的,因此不会对输 入文件有任何影响;而hold space则作为后备缓冲区使用。 sed针对输入中的每一行都会执行一个系列命令:首先,从标准输入流 读取一行,移除换行符,然后存入pattern space中,接着执行指定的命令。 每个命令都有一个可选的地址(也可能是一个正则表达式匹配),这个地址作 为一个执行前的测试,指定了需要对那些行进行操作。当前行只有匹配的情 况下才会执行命令。 当指定所有的命令都执行完了之后,sed默认会将pattern space中的 内容打印到标准输出中,如果指定了-n选项,则会禁止这种默认的打印行为。 如果读取本行时移除了行尾的换行符,则在打印了pattern space中的内容后 会再打印一个换行符。这样针对本行的操作就完成了,然后sed会读取下一行 的内容,再次执行相同的操作。 非指定了一些特殊的命令(例如D命令),否则pattern space中的内容 会在处理完一行之后删除,但hold space中的内容在处理完每一行时不会被 删除。 例 1. 在匹配式样regex的行之前插入一空行 sed '/regex/{x;p;x;}' x Exchange the contents of the hold and pattern spaces. p Print out the pattern space (to the standard output). This command is usually only used in conjunction with the `-n' command-line option. 令执行过程如下:先读入一行,删除换行符,然后将其保存到 pattern space中,然后用/regex/正则表达式匹配pattern space中的内容, 如果匹配的话则执行后续的命令;如果不匹配则执行默认的打印pattern space中内容的操作,然后读取下一行。 如果匹配的话,第一个x命令将pattern space和hold space中的内 容交换,由于此时hold space内容为空,实际的效果就是将pattern space的内容移动到hold space中,然后用p命令打印hold space的内容, 由于此时hold space为空,所以会打印一个空行,接着第二个x命令会又一 次交换pattern space和holdspace的内容,实际效果是原先读入的那一行 又会从hold space移动到patternspace中,最后打印此行内容。所以以上 命令的结果就是在每一个匹配/regex/的行之前插入一个空行。 理解上述命令的关键在于当pattern space为空时,p命令会打印一 个空行,而不是一个空字符串。这涉及到sed的工作原理:sed会在读入一 行后,去掉行尾的换行符,然后将其内容存入pattern space中,打印时会 在最后加一个换行符。所以当pattern space为空时,p命令会先打印一个 空字符串,然后再打印一个换行符。 2. sed中如何选择特定的行 sed中有一些指定行范围的方法,用行号指定和用正则表达式指定,以 及两者结合起来指定。里面涉及到行号匹配的时候,如果指定了 -i或者-s选项的话则是相对于当前文 件。否则是相对于整个输入流。 N 匹配输入中第N行。 FIRST~STEP 从第FIRST行开始,每隔 STEP行选择一行。最终选择行的行号 等于 FIRST+(N*STEP) 。1~1选择所有行(在这里没什么意义),1~2选择奇数行,2~2选择偶 数行等等。 $ 匹配最后一行。 /REGEXP/ 选择所有匹配这个正则表达式的行。 \%REGEXP% 同样是正则表达式匹配,上面的%可以换成任何字符,主要用 于匹配的内容包含大量需要转义的字符的情况下,例如匹配路径时。 /REGEXP/I, \%REGEXP%I 同上,忽略大小写的正则表达式匹配。 /REGEXP/M, \%REGEXP%M 同上,多行匹配。M表示multi-line。不使用M时,^和$只能 匹配pattern space的开始和结尾的位置,如果使用了M修饰符,且 pattern space中间有换行符的话,^还会匹配换行符后下一行开头 的位置,$还会匹配换行符和它之前的字符中间的位置。 使用这个修饰符要注意,它不会改变sed每 次读取一行的默认行为。正因为sed的默认操作行为,一般情况下 pattern space中没有换行符。只有在pattern space中间有换行符 的情况下M修饰符才会有效果,可以通过N命令来达到这个目的。 例 2. 模式匹配时M修饰符的作用 ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc\nd" | sed -n 'N;s/^[a-z]$/X/p' ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc\nd" | sed -n 'N;s/^[a-z]$/X/Mp' X b X d ~/pro/3.System_Config/tools/sed$ sed首先将"a"读入pattern space,接着执行N命令,此时 pattern space中的内容为"a\nb",第一个sed命令没有使用M修饰符, /^[a-z]$/中的$不能匹配"\n"前面的位置,所以匹配失败,不执行 替换和打印命令。第二个sed命令使用了M修饰符,成功匹配,即 /^[a-z]$/匹配了"a"(其中的$匹配了"a"和"\n"中间的位置),将其 替换为"X",此时pattern space中的内容为"X\nb",然后用p命令打 印。注意由于在用N命令将"b"所在行加到pattern space的时候删去 了"b"所在行尾的换行符,所以在打印完"b"字符后sed会添加一个换 行符,就形成了结果中的前两行的输入,后续的执行过程相同。 如果没有指定行号匹配条件,则所有的行都匹配。如果指定了行号 或者正则表达式,则只有与之匹配的行才选择。 另外还可以用范围来选择特定的行,范围是用逗号分割的两个表达 式,表达式可以用上面的任意一种方式指定。如果范围内的第二个值小于 等于第一个值的话,那么只有与第一个值所匹配的单行匹配。 Gnu sed 支持几种特殊的指定地址范围的方法: 0,/REGEXP/ 这种方式会使 /REGEXP/从第一行开始匹配,而常规 的 1,/REGEXP/ 则只能让/REGEXP/从第二行开始匹配。 当/REGEXP/匹配第一行时,这 两种方式的差异就会体现出来。 例 3. 比较 0,/REGEXP/ 和 1,/REGEXP/ ~/pro/3.System_Config/tools/sed$ cat a.txt abcdef xxx yyy abcdef xxx yyy ~/pro/3.System_Config/tools/sed$ sed -n '1,/abc/p' a.txt abcdef xxx yyy abcdef ~/pro/3.System_Config/tools/sed$ sed -n '0,/abc/p' a.txt abcdef ADDR1,+N 匹配从第ADDR1行以及以后 的N行。 ADDR1,~N 匹配从第ADDR1行开始,直 到N的倍数行。 例 4. 比较 ADDR1,+N 和 ADDR1,~N ~/pro/3.System_Config/tools/sed$ cat c.txt abcdef xxx yyy zzz ~/pro/3.System_Config/tools/sed$ sed -n '1,+3p' c.txt abcdef xxx yyy zzz ~/pro/3.System_Config/tools/sed$ sed -n '1,~3p' c.txt abcdef xxx yyy 3. sed的命令行选项 -n 默认情况下,sed会打印pattern space中的内容,这个选项禁止 sed的默认打印行为。 -e SCRIPT 指定欲执行的命令,可以同时指定多个。sed会对pattern space中的内容依次执行每个-e选项指定的命令。 ~/pro/3.System_Config/tools/sed$ echo -e "abc\nbcd\ncde" | sed -n -e '/b/p' -e '/d/p' abc bcd bcd cde 可以看到"bcd"所在的行会被打印两次。 -f SCRIPT-FILE 指定执行文件中的命令。 -i [SUFFIX] 没有SUFFIX参数的时候,默认情况下sed不会修改输入的源文件, 会将内容打印到标准输出,使用了这个选项之后它会将输出保存到一 个临时文件,当所有命令执行完成之后,将临时文件重命名为输入的 源文件。 如果指定了SUFFIX,会将输入的源文件作一个备份。当SUFFIX 里不包含星号时,备份的文件名为源文件名+SUFFIX;当SUFFIX里含一 个或者多个星号时,会将星号替换为源文件名,这种方式可以给备份 文件加上前缀,而不是简单地加一个后缀,甚至SUFFIX里可以包含路 径名,这样就可以将源文件备份到另一个文件夹里(前提是那个路径需 存在)。 例 5. -i选项的值 SUFFIX不含星号的情况 ~/pro/3.System_Config/tools/sed$ ls *c* c.txt ~/pro/3.System_Config/tools/sed$ cat c.txt abcdef xxx yyy zzz ~/pro/3.System_Config/tools/sed$ sed -ibackup 's/^.//g' c.txt ~/pro/3.System_Config/tools/sed$ ls *c* c.txt c.txtbackup ~/pro/3.System_Config/tools/sed$ cat c.txt bcdef xx yy zz ~/pro/3.System_Config/tools/sed$ cat c.txtbackup abcdef xxx yyy zzz 例 6. -i选项的值 SUFFIX包含星号的情况 ~/pro/3.System_Config/tools/sed$ cat c.txt abcdef xxx yyy zzz ~/pro/3.System_Config/tools/sed$ ls *c* c.txt ~/pro/3.System_Config/tools/sed$ sed -ibackup* 's/^.//g' c.txt ~/pro/3.System_Config/tools/sed$ ls *c* backupc.txt c.txt ~/pro/3.System_Config/tools/sed$ cat c.txt bcdef xx yy zz ~/pro/3.System_Config/tools/sed$ cat backupc.txt abcdef xxx yyy zzz -l N, --line-length=N 指定用l命令显示时的最长行的长度,如果文本大于这个长度会被 折行处理。折行时行尾会加一个反斜杠转义换行符。 N的长度默认为70。 例 7. -l N选项 本例中d.txt只包含一行内容,为100个字符a。 ~/pro/3.System_Config/tools/sed$ cat d.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ~/pro/3.System_Config/tools/sed$ sed -n 'l' d.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa$ ~/pro/3.System_Config/tools/sed$ sed -n -l 50 'l' d.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aa$ --posix 相对于POSIX sed, GNU sed 使用了一些扩展的功能,如果指定 这个选项会更加方便移植,但同时会禁用这些扩展功能。 -b, --binary 将输入文件文件当作二进制文件来处理。在dos/windows平台上, 由于行分隔符是由CR和LF两个字符组成,如果不指定这个选项,sed也会 把这个两个字符的组合当成行分隔符。如果指定了这个选项,sed会将 LF当作换行符,这样CR就成了每行的最后一个字符。 --follow-symlinks 是否跟随符号链接。这个选项只在支持符号链接的平台上存在, 并且只有同时使用了-i选项时才会起作用。如果输入 文件是到另一个文件符号链接,指定了这个选项会跟随符号链接。默认 情况下不跟随。 -r, --regexp-extended 使用扩展的正则表达式。 -s, --separate 默认情况下,sed 会将命令行指定的所有输入文件当作一个连续 的输入流来看待。这个选项会禁止这个特征,将文件独立对待,这会影 响某些匹配选项。例如$默认情况下会匹配整个输入流的最后一行,如果 指定了-s选项,$会匹配每个文件的最后一行。 -u, --unbuffered 最小化输入和输出的缓冲区大小。如果输入是从类似于tail -f这 种管道取得的,这个选项会尽可能快地输出结果。 4. sed命令 # 注释 q [EXIT-CODE] 这个命令只能用于单个地址的情况。 q命令会让sed在打印完当前pattern space中的内容后立即退出, 如果没有用-n选项来禁止默认的打印行为的话。使 用可选的 [EXIT-CODE]代码 作为sed的退出码。 d 删除当前pattern space中的内容并立即开始下一个循环,即 sed开始处理下一行。 p 将当前pattern space中的内容打印到标准输入,这个选项一般 与-n选项一起使用。 n n命令会立即用读取的下一行的内容取代当前pattern space中的内容。 如果没有用-n选项来禁止默认的打印行为的话,n 命令会先打印完当前pattern space中的内容。如果到了输入的末尾, 即不能读取更多的内容,则sed立即退出,不执行n之后的命令。 { COMMAND } {和}中间可以包含一组命令,用这种方式可以将这一组命令同 时作用到某一个地址上。 s/REGEXP/REPLACEMENT/FLAGS 其中的/可以使用其它单个字符替换。 /REPLACEMENT中可以使用一些特 殊的字符,这些字符有特殊的含义。 \N 引用前面匹配的第N个捕 获性括号中的内容。 L 将替换的内容都转换成小写字母,直到遇到\U或者\E。 l 将下一个字符转换成小写字母。 U 将替换的内容都转换成大写字母,直到遇到\L或者\E。 E 停止\L或者\U的字母大小写转换。 FLAGS为替换命令的修饰符。可 以包含一个或者多个以下字符。 g 全局替换。默认为只替换第一个匹配的项。 NUMBER 替换第NUMBER个匹配的项。 U 将替换的内容都转换成大写字母,直到遇到\L或者\E。 E 停止\L或者\U的字母大小写转换。 p w FILE-NAME 如果成功替换,将结果输出到 FILE-NAME文件中。 e 这是GNU sed的一个扩展命令,如果成功执行了替换操作, 则替换的结果会作为一个shell命令来执行,然后将命令运行的 输出存入pattern space。 ~/pro/3.System_Config/tools/sed$ echo "date" | sed -n 's/^//ep' Sat Oct 22 19:46:32 CST 2011 ~/pro/3.System_Config/tools/sed$ cat g.txt ls -l ~/pro/3.System_Config/tools/sed$ sed -n 's/^//ep' g.txt total 156 -rw-r--r-- 1 forfun forfun 67 Oct 17 17:21 Makefile -rw-r--r-- 1 forfun forfun 30 Oct 21 12:33 a.txt ...... -rw-r--r-- 1 forfun forfun 22598 Oct 22 19:49 sed.xml -rw-r--r-- 1 forfun forfun 19550 Oct 21 15:10 sed.xml~ -rw-r--r-- 1 forfun forfun 35130 Oct 8 15:05 sed1line.txt ~$ echo "xxx12yyy" | sed -n -r 's/(.*?)([0-9]+)(.*?)/echo \1; echo \2+1|bc; echo \3/e; s/\n//gp' xxx13yyy I, i 忽略大小写。 M, m 即匹配多行,与行匹配的M修饰符作用相同,见M修饰符。 y ~/pro/3.System_Config/tools/sed$ echo "abc" | sed 'y/ab/AB/' ABc a\ TEXT ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2a\ > xxx' a xxx b xxx c i\ TEXT ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2i\ > yyy' yyy a yyy b c c\ TEXT ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2c\ > zzz' zzz c ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2=' 1 a 2 b c = ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2=' 1 a 2 b c l N ~/pro/3.System_Config/tools/sed$ echo -e "\t\b" ~/pro/3.System_Config/tools/sed$ echo -e "\t\b" | sed 'l' \t\b$ ~/pro/3.System_Config/tools/sed$ cat d.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ~/pro/3.System_Config/tools/sed$ sed -n 'l 40' d.txt aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaa$ r FILENAME ~/pro/3.System_Config/tools/sed$ cat c.txt abcdef xxx yyy zzz ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2r c.txt' a abcdef xxx yyy zzz b abcdef xxx yyy zzz c w FILENAME ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc" | sed '1,2w h.txt' a b c ~/pro/3.System_Config/tools/sed$ cat h.txt a b D ~/pro/3.System_Config/tools/sed$ cat i.txt abc 123 def456 ghi ~/pro/3.System_Config/tools/sed$ sed '/[a-z]/D' i.txt 123 N P ~/pro/3.System_Config/tools/sed$ echo -e "a\nb\nc\nd" | sed 'N;P' a a b c c d

转载于:https://www.cnblogs.com/happydpc/archive/2012/08/18/sed.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值