1、追加下一行文本到Pattern Space中(N command)
正如大写的H和G命令是追加而非替代,大写的N命令也是把下一行文本追加到Pattern Space中,而非替换原Pattern Space中的内容。
我们先前讨论过,小写的n命令是打印当前的Pattern Space中的内容,清空Pattern Space中的内容,读取下一行内容到Pattern Space中,然后恢复它接下来的命令流程。
但是大写的N命令,不会打印当前Pattern Space中的内容,也不会清除Pattern Space;它会在Pattern Space中的当前文本后添加一个新行(\n),从输入文件中读取下一行文本追加到Pattern Space中,然后接着执行剩下的sed命令。
示例:打印雇员的姓名和职位,中间用分号隔开:
$ sed -e '{N;s/\n/:/}' empnametitle.txt John Doe:CEO Jason Smith:IT Manager Raj Reddy:Sysadmin Anand Ram:Developer Jane Miller:Sales Manager
该示例的执行流程可以用下图表示:
2、打印多行中的第一行(P command)
小写的p命令会打印Pattern Space中的所有内容,而大写的P命令则只打印Pattern Space中的第一行内容(到第一个\n为止)。
示例:打印所有经理的名字:
$ sed -n -e 'N' -e '/Manager/P' empnametitle.txt Jason Smith Jane Miller
3、删除多行中的第一行(D command)
4、循环和分支(b command and :label)
Note: You can also execute just the b command (without any label name). In this case, sed jumps to the end of the sed script file.
The following example combines the employee name and title (from the empnametitle.txt file) to a single line separated by : between the fields, and also adds "*" in front of the employee name, when that employee's title contains the keyword "Manager".
$ vi label.sed #!/bin/sed -nf h;n;H;x s/\n/:/ /Manager/!b end s/^/*/ :end p
In the above example, you already know what "h;n;H;x" and "s/\n/:/" does, as we discussed those in our previous examples. Following are the branching related lines in this file.
- /Manager/!b end - If the lines doesn't contain the keyword "Manager", it goes to the label called "end". Please note that the name of the label can be anything you want. So, this executes "s/^/*/" (add a * in the front), only for the Managers.
- :end - This is the label.
Execute the above label.sed script:
$ chmod u+x label.sed
$ ./label.sed empnametitle.txt John Doe:CEO *Jason Smith:IT Manager Raj Reddy:Sysadmin Anand Ram:Developer *Jane Miller:Sales Manager
5、使用t命令循环
The sed command t label branches the execution flow to the label only if the previous substitute command was successful. That is, when the previous substitution was successful, sed jumps to the line marked by the label and continues executing the rest of the commands from there, otherwise it continues normal execution flow.
The following example combines the employee name and title (from the empnametitle.txt file) to a single line separated by : between the fields, and also adds three "*" in front of the employee name, when that employee's title contains the keyword "Manager".
$ vi label-t.sed #!/bin/sed -nf h;n;H;x s/\n/:/ :repeat /Manager/s/^/*/ /\*\*\*/!t repeat p
$ chmod u+x label-t.sed
$ ./label-t.sed empnametitle.txt John Doe:CEO ***Jason Smith:IT Manager Raj Reddy:Sysadmin Anand Ram:Developer ***Jane Miller:Sales Manager
In the above example:
• The following code snippet does the looping.
:repeat /Manager/s/^/*/ /\*\*\*/!t repeat
- /Manager/s/^/*/ - If it is Manager, it adds a single * in front of the line.
- /\*\*\*/!t repeat - If the line doesn't contain three *s (represented by /\*\*\*/!), and if the previous substitute command is successful by adding a single star in front of the line, sed jumps to the label called repeat (this is represented by t repeat)
- :repeat - This is just the label