Sed 有两种内部存储空间:
- Pattern Space:sed执行流程中,将从文件中读取的文本行放置到这个空间,并在此空间中修改文本。
- Hold Space:这是sed额外的一个可用的缓冲空间,sed可以用之来存放临时数据。Sed允许我们将数据在Pattern Space和Hold Space间来回移动,但是无法在Hold Space中的数据上执行传统的sed 命令。我们已经知道,Pattern Space中的数据在每次的sed执行循环后会清空,但是Hold Space中的数据不会被清空。
请创建一个以下的文本来作为示例使用:
$ vi empnametitle.txt John Doe CEO Jason Smith IT Manager Raj Reddy Sysadmin Anand Ram Developer Jane Miller Sales Manager
1、交换Pattern Space和Hold Space中的数据(x command)
假设Pattern Space中包含“Line 1”,Hold Space中包含“Line 2”,执行x命令后,Pattern Space中将包含“Line 2”,而Hold Space中将包含“Line 1”。该命令自身没有太大的用处,但是结合一些其他的命令,将会非常有用。
示例:打印经理的名字,寻找关键字“Manager”,并打印其前一行。
$ sed -n -e 'x;n' -e '/Manager/{x;p}' empnametitle.txt Jason Smith Jane Miller
示例说明:
- {x;n} x命令交换Pattern Space和Hold Space中的内容;n读取下一行到Pattern Space中。也就是说,该命令组合会将当前行存储到Hold Space中,而读取下一行放到Pattern Space中。对于示例文件来说就是,将姓名放到了Hold Space中,然后取其职位放到Pattern Space中。
- /Manager/{x;p} 如果Pattern Space中的内容含有关键字“Manager”,则交换Pattern Space和Hold Space中的内容,然后打印Pattern Space中的内容。也就是说如果职位中含有“Manager”,则打印其名字
2、拷贝Pattern Space中的内容到Hold Space中(h command)
和x命令的区别是,不会改变Pattern Space中的内容。
假设Pattern Space中包含“Line 1”,Hold Space中包含“Line 2”,执行h命令后,Hold Space中将包含“Line 1”,而Pattern Space中依然是“Line 1”。
示例:打印经理的名字
$ sed -n -e '/Manager/!h' -e '/Manager/{x;p}' empnametitle.txt Jason Smith Jane Miller
示例说明:
- /Manager/ ! h - 如果Pattern Space中的内容不包含关键字“Manager”,将Pattern Space中的内容拷贝到Hold Space中(在这个示例中,可能是员工姓名,也可能是非经理的职位名称)。不像上个例子,我们这里没有用n命令去读取下一行,而是按照常规的sed执行流程执行。
- /Manager/{x;p} - 如果Pattern Space中的内容包含关键字“Manager”,则交换Hold Space和Pattern Space中的内容并打印Pattern Space中的内容。
3、将Pattern Space中的内容追加到Hold Space中(H command)
大写的H命令可以将Pattern Space中的内容追加到Hold Space中。
假设Pattern Space中持有内容“line 1”,而Hold Space中持有内容“line 2”,则执行H命令后,Pattern Space中的内容仍然是"line 1",而Hold Space中的内容则变为“line 2\n;line1”
示例
$ sed -n -e '/Manager/!h' -e '/Manager/{H;x;p}' empnametitle.txt Jason Smith IT Manager Jane Miller Sales Manager
4、将Hold Space中的内容拷贝到Pattern Space中(g command)
示例:
$ sed -n -e '/Manager/!h' -e '/Manager/{g;p}' empnametitle.txt Jason Smith Jane Miller
5、将Hold Space中的内容追加到Pattern Space中(G command)
$ sed -n -e '/Manager/!h' -e '/Manager/{x;G;s/\n/:/;p}' empnametitle.txt Jason Smith:IT Manager Jane Miller:Sales Manager