这篇记录一下sed的基本用法,建议看下sed与awk第三版里面介绍的很详细,sed通过正则表达式匹配出命令处理文本,如果对正则不熟悉是件很头疼的事。注意以下脚本都是在脚本文件上测试的使用命令sed -f scrift files
1.sed先读取一行至模式空间,取前先清除以前模式空间内容(多行模式下读取命令N除外),脚本从脚本顶部开始处理模式空间的内容,处理一条命令更新模式空间内容,新的命令在更新后的模式空间上进行,到达脚本底部后默认送往屏幕显示也可以使用-n禁止这个默认输出,sed 对源文件内容不做修改。
2.sed命令可以指定0个1个或2个地址,每个地址是一个描述模式,行号或行寻址符号的正则表达式。
3.sed命令 格式sed [options] 'command' files; sed [options] -f scriptfile files
3.1 追加,插入,更改
a\ 在当前行后面加入一行文本。 i\ 在当前行上面插入数据,新插入的数据不会被读入处理。 c\ 改变行的文本,如1~3行变成123456789 1,3c\123456789 $a\end of file 在最后一行后加入 $i\end of file 在最后一行前加入 $c\end of file 替换掉最后一行 这里碰到奇怪的问题,sed与awk第三版说aic会修改模式空间的内容,自带帮助文件没提及,测试发现aic命令执行后后面的命令没被执行,如 1{ c\1234 = = p p p } 更改第一行内容为1234,后面打印行号和测试的输出,但结果后面的命令不执行了,如果知道请告知一下谢谢。
3.2 替换 [address]s/pattern/replacement/flags 用replacement替换正则表达式pattern。flag可以是一下标示。
n 1~512之间的数字,表示只替换第n次出现的pattern g 全部替换,没有g只替换第一次出现的pattern p 只是打印 W file 写入文件 如果没有匹配地址那么匹配全部行,和地址不同地址的定界符为斜杠/,正则表达式可以使用任意字符分割如s/444/111/,可以写成 s244421112,现在分割 符号是2,当然这是例子最好不要这样写。如果表达式内包含定界符那么需要用反斜杠来转义它。 在pattern部分我们可以用\(和\)来分块,在替换部分repalcement可以使用\n(n是数字)来表示pattern的第几块,使用&表示整个pattern匹配出来的字符 串, 例子如文档中多处出现google里面的o是不定的,但发现少写了个e。可以 s/\
/&e/g,\<和\>是锚定单词,&e表示只在原来基础上加个e。 例子如google内o不定发现少了个g,替换时要保留原来o的个数怎么办呢?这就需要用块了,s/\ /g\1gle/g,这里pattern内用\(和\)分了 块,然后在replacement内调用块内的内容\1。
3.3 删除行d,如删除1,3行 1,3d
3.4 列表l 列出不能打印字符的清单,将不能打印的字符显示为两个数字显示的ascii代码,如\n \t...
3.5 转换 [address]y/abc/xyz/
这个命令按位置将字符串abc中的每个字符转换为xyz中对应的字符。
如转换大小写可以y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/3.6 打印 p
3.7 打印行号 =
3.8 读入下一行 n 用下一命令处理,而不是重新处理,如下找到行111的行处理后,下一行如果是空行那么删除下一行
/111/{ s/111/222/; n; /^$/d; } 实际上,next命令导致输入的下一行取代模式空间的当前行,脚本的后续命令作用于替换后的行。
3.9 读写文件
r file 读入文件不存在也不会报错 w file 写入文件如果不存在将创建一个,如果存在那么首次写入清空旧数据,以后写入为追加写入。
3.10 退出 q 退出sed
如匹配到111的行后退出 sed /111/q file
3.11 ! 表示后面的命令对所有没有被选定的行发生作用。
3.12 = 打印当前行
3.13 # 注释行
高级命令,sed通常读一行至模式空间,并逐条执行脚本中的命令,脚本结束时输出这一行并清空模式空间,然后读下一行至模式空间如此循环,sed的多行模式命令可以一次读入多行然后进行匹配处理,如处理跨行的词组。
3.14 多行模式空间 N D P 对应单行模式下的n d p
P只打印多行模式的第一行,p打印整个模式控件内容。P经常出现在N之后和D之前。 D只删除多行模式的第一行,不读新入行至模式空间,但会回到脚本顶端,重执行脚本,d 删除模式空间的内容,导致读入新行并重新执行脚本 N读取新的行并添加只模式空间现有内容后,读入的行自动用换行\n分割开来。读入多行模式空间内的所有行可以看成是带有换行\n的单行数据,^匹配第一 行的开头$匹配最后一行的结尾。例如替换跨行的词组hello sed ,替换成单行。 ex1:替换相邻行 hello sed 替换成一行 hello sed /hello$/{ N; s/hello\nsed/hello sed/ } ex2: 将多个空白行替换成一个空白行 /^ *$/{ N; /^ *\n$/D; } 如果把D改成小写d,那么当空白行为偶数时全部空白被删除,奇数时保留1行,因为模式空间凑够两行后d命令删除空间内的全部并取下一行,使用D先匹配到 一行空白行,取下一条如果是连续空白行那么删除第一行后,会回到脚本顶端,重新按当前模式空间的内容执行脚本。
3.15 采用保持空间来保存模式空间内容,使用H h G g x操作保持空间的内容
模式空间是当前处理的缓冲区,还有个个保持空间,类似剪切板,可以将处理的内容复制到保持空间, hold h/H 将模式空间的内容复制/追加至保持空间 get g/G 将保持空间的内容赋值/追加至模式空间 x 模式空间和保持空间的内容互换 h 拷贝选中内容到保持空间,以前缓存的内容被清掉。 H 追加选中内容到保持空间,以前缓存的内容不变,这样可以缓存多行。 g 获取保持空间内容,并 替换 模式空间中的内容。 G 获取保持空间内容,并 追加 模式空间的 后面。
3.16 使用分支和条件指令 : b t T
分支(b)和测试(T/t)命令脚本中的控制转移到包含特殊标签的行。如果没有标签那么转移到脚本结尾处。 分支b用于无条件转移 [address] b [label] label可选,当无label时跳至脚本结尾。 测试t用于条件转移 [address] t [label] label可选,当无label时跳至脚本结尾。如果当前匹配地址的行上进行了成功的替换,那么test命令会转到标 签处 测试(T)和(t)相反 用于条件转移 [address] t [label] label可选,如果当前匹配地址的行上进行了替换失败,那么test命令会转到标签处 T 和 t测试的是s///替换命令的结果 标签本身占有一行使用:开头,使用b label无条件跳转, 使用分支b跳转方式删除多行空白,替换成一行空白,当读到空白行时循环读出,然后将多行模式空间的空白行替换成单一空白行 /^ *$/{ :rdn N; /^\( *\n*\)\{1,\}$/b rdn; s/^\( *\n*\)\{1,\}\n/\n/ } 使用测试t跳转方式删除多行空白,替换成一行空白,当读到空白行时,读下一行然后替换两空白行为一空白行,如替换成功接着读下一行,直到替换失败 /^ *$/{ :loop N; s/^\( *\n*\)\{1,\}$//; t loop }
4.[options]
4.1 -e command, --expression=command 允许多台编辑。 4.2 -h, --help 打印帮助,并显示bug列表的地址。 4.3 -n, --quiet, --silent 取消默认输出。 4.4 -f, --filer=script-file 引导sed脚本文件名。 4.5 -V, --version 打印版本和版权信息。
5.元字符集
^ 锚定行的开始 如匹配1111开头的行,/^1111/ $ 锚定行的结束 如匹配aaaa结尾的行,/aaaa$/ . 匹配一个字符 包括换行符号 * 匹配零或多个字符 [] 匹配 一个 指定范围的字符 如[123]k匹配1k 2k 3k [^]匹配一个不在指定范围内的字符 \(..\) 保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。 & 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。 \< 锚定单词的开始,如:/\
锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。 x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个o的行。 x\{m,\} 重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。 x\{m,n\}重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。 \+ 至少一个匹配 \? 0个或1个 \| `REGEXP1\|REGEXP2' Matches either REGEXP1 or REGEXP2. 如删除包含111或222的行/111\|222/d
6.嵌套分组命令
sed使用大括号将一个地址嵌套在另一个地址中,或相同地址应用多个命令,例如匹配3~8行内匹配包含444的地址sed脚本文件可以如下 3,8{ /444/{ s/444/333/ 其他指令 } } 上面例子s/444/333/前又可以加匹配地址,每个命令可以有自己的地址并允许多层嵌套,如果命令之间有个分号,那么可以多个sed命令放同一行,有些命令 会把;当输出数据了,如a,未阅读方便不提倡写在同一行。一些sed说明注释智能在第一行出现,命令内不能有多余空格,大括号后不能有空格,右大括号要单 独一行的约束,但是再我使用的sed版本GNU sed 版本 4.2.1并没有这些限制。