http://coolshell.cn/articles/9104.html/comment-page-1
sed命令参数
-r或者--regexp-extended
使用拓展的正则表达式,即'egrep'命令接受的
正则表达式基础:
^ 表示一行的开头。如:/^#/ 以#开头的匹配。$ 表示一行的结尾。如:/}$/ 以}结尾的匹配。
\< 表示词首。 如 \<abc 表示以 abc 为首的詞。
\> 表示词尾。 如 abc\> 表示以 abc 結尾的詞。
. 表示任何单个字符。
* 表示某个字符出现了0次或多次。
[ ] 字符集合。
使用 -i 参数直接修改文件内容:
$ sed -i "s/from/to/g" input
在每一行最前面加点东西:
$ sed 's/^/something/g' input
找到第一个打印,退出,p print,q quit 找到一个就退出
$ sed -n '/12345/{p;q}' fin.txt
在每一行最后面加点东西:
$ sed 's/$/something/g' input
仅替换第三行
$ sed "3s/from/to/g" input
替换第3到6行
$ sed "3,6s/from/to/g" input
只替换每一行的第一个:
$ sed 's/from/to/1' input
只替换每一行的第二个:
$ sed 's/from/to/2' input
只替换第一行的第3个以后的:
$ sed 's/from/to/3g' input
使用&来当做被匹配的变量,然后可以在基本左右加点东西:
$ sed 's/old/some & some/g' input
或者使用正则后项引用
$ sed 's/\(old\)/some \1 some/g' input
sed命令
0:s命令,替换命令
完整格式s/REGEXP/REPLACEMENT/FLAGS
其中/可由其它字符代替,该字符在REGEXP或者REPLACEMENT中必须转义
REPLACEMENT可以使用/N引用REGEXP匹配的第N部分
REPLACEMENT中
/L将字符转化为小写,直到遇到/E或者/U
/l将后面一个字符小写
/U将字符转化为小写,直到遇到/E或者/L
/u将后面一个字符大写
FLAGS
为空,默认应用于第一个匹配
g,替换,应用于所有的匹配,不仅仅是默认的第一个
NUMBER,替换,应用第NUMBER个匹配
p,打印
I i,替换,大小写不敏感
m M,替换,多行匹配
e,将匹配后的数据当作shell执行
$ sed 'N;s/from/to/' input
$ sed 'N;s/\n/ /' input
2:a命令和i命令
a命令就是append, i命令就是insert,它们是用来添加行的。如:
# 其中的1i表明,其要在第1行前插入一行(insert)
$ sed "1 i new line" input
# 其中的1a表明,其要在最后一行后追加一行(append)
$ sed "1 a new line" input
运用匹配来添加文本:
# 注意其中的/key/a,这意思是匹配到/key/后就追加一行
$ sed "/key/a newline" input
3:c命令
c 命令是替换匹配行
#替换第二行
$ sed "2 c new line" input
#替换匹配的行
$ sed "/key/c new line" input
4:d命令
delete 删除匹配行
#删除匹配行
$ sed '/key/d' input
#删除第二行
$ sed '2d' input
#删除第二行后的所有行
$ sed '2,$d' minput
5:p命令
打印命令
# 打印匹配行,可以看到匹配行被输出2次, 这是因为sed处理时会把处理的信息输出
$ sed '/key/p' input
# 使用n参数,不打印原始信息,这样就只打印匹配的行了,相当于grep
$ sed -n '/key/p' input
# 从匹配一个key的行打印到匹配另一个模式的行
$ sed -n '/key1/,/key2/p' input
# 从第一行打印到匹配key成功的那一行
$ sed -n '1,/key/p' input
几个概念
sed 命令格式
$ sed [Address]命令 input
0:Pattern Space
第零个是关于-n参数的,大家也许没看懂,没关系,我们来看一下sed处理文本的伪代码,并了解一下Pattern Space的概念:
foreach line in file {
//放入Pattern_Space
Pattern_Space <= line;
// 对每个pattern space执行sed命令
Pattern_Space <= EXEC(sed_cmd, Pattern_Space);
// 如果没有指定 -n 则输出处理后的Pattern_Space
if (sed option hasn't "-n") {
print Pattern_Space
}
}
1:Address
第一个是关于address,几乎上述所有的命令都是这样的(注:其中的!表示匹配成功后是否执行命令)
[address[,address]][!]{cmd}
address可以是一个数字,也可以是一个模式,你可以通过逗号要分隔两个address 表示两个address的区间,
# 表示删除第3行
$ sed '3d' input
# 表示删除第1-3行
$ sed '1,3d' input
# 表示删除匹配行
$ sed '/key/d' input
# 其中的+3表示匹配行及后面连续3行
$ sed '/key/,+3s/^/# /g' input
2:命令打包
第二个是cmd可以是多个,它们可以用分号分开,可以用大括号括起来作为嵌套命令。下面是几个例子:
# 对3行到第6行,执行删除命令/key/d
$ sed '3,6 {/key/d}' input
# 对3行到第6行,匹配/key1/成功后,再匹配/key2/,成功后执行d命令
$ sed '3,6 {/key1/{/key2/d}}' input
# 从第一行到最后一行,如果匹配到key,则删除之;如果前面有空格,则去除空格
$ sed '1,${/key/d;s/^ *//g}' input
3:Hold Space
第三个我们再来看一下 Hold Space
接下来,我们需要了解一下Hold Space的概念,我们先来看四个命令:
g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容
sed是一个非交互式的流编辑器(stream editor)。非交互式是指使用sed只能在命令行下输入编辑命令来编辑文本,然后在屏幕上查看输出;而流编辑器是指sed每次只从文件(或输入)读入一行,然后对该行进行指定的处理,并将结果输出到屏幕(除非取消了屏幕输出又没有显式地使用打印命令),接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。
sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区(pattern space)中的内容,处理完成后,把pattern space内容给hold space,把缓冲区(pattern space)的内容送往屏幕,然后把pattern space置空。接着读下一行,处理下一行,直到文件末尾。
几个例子:
$ cat t.txt
one
two
three
$ sed 'H;g' t.txt
one
one
two
one
two
three
#使用sed实现tac翻转文件内容功能
$ sed '1!G;h;$!d' t.txt
three
two
one
其中的 ’1!G;h;$!d’ 可拆解为三个命令
1!G —— 只有第一行不执行G命令,将hold space中的内容append回到pattern space
h —— 第一行都执行h命令,将pattern space中的内容拷贝到hold space中
$!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行