sed之G、H、g、h使用

原创
2015/09/15 16:40
阅读数 306

sed如何处理数据?

sed在正常情况下,将处理的行读入模式空间(pattern space),脚本中的“sed-command(sed命令)”就一条接着一条进行处理,知道脚本执行完毕。然后该行呗输出,模式(pattern space)被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

 

什么是Pattern Space,什么是Hold Space?

pattern space相当于车间sed把流内容在这里处理。

hold space相当于仓库,加工的半成品在这里临时储存。

PS:你可以将pattern space看成是一个流水线,所有的动作都是在“流水线”上执行的;而hold space是一个“仓库”,“流水线”上的东东都可以放到这里。

为什么要使用sed高级命令(G、H、g、h、n、N、x)?

由于各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。

sed命令:

+ g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除

+ G:[address[,address]]G 将hold space中的内容append到pattern space\n后

+ h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除

+ H:[address[,address]]H 将pattern space中的内容append到hold space\n后

+ d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中

+ D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行

PS:不论是使用G、g还是H、h,它们都是将hold space里面的内容“copy”到pattern space中或者将pattern space中的内容“copy”到hold space中。

附上英文的解释(注意其中的高亮单词):

The "h" command copies the pattern buffer into the hold buffer. The pattern buffer is unchanged.

Instead of exchanging the hold space with the pattern space, you can copy the hold space to the pattern space with the "g" command. This deletes the pattern space. If you want to append to the pattern space, use the "G" command. This adds a new line to the pattern space, and copies the hold space after the new line.

示例一:


#!/bin/bash
file=/tmp/volume_status_$$
ret=/tmp/volume_status_ret_$$

scnas volume status | grep -v "Scnas process" | grep -v "NFS Server" | grep -v "Self-heal" | sed s/'Status of volume: '/'卷名:'/g | grep -v "\-\-\-" | sed s/'Brick '//g >$file

while read line;do
	echo $line | grep "卷名" 1>/dev/null
	if [ $? -ne 0 ];then
		brick=$(echo $line | awk -F ' ' '{printf $1}')
		statu=$(echo $line | awk -F ' ' '{printf $3}')
		if [ X$statu == 'XY' ];then
			statu='在线'
			printf "$brick\t\t$statu\n" >>$ret
		elif [ X$statu == 'XN' ];then
			statu='离线'
			printf "<font color='red'>$brick\t\t$statu</font>\n" >>$ret
		fi
	else
		echo " " >>$ret
		printf "$line\n" >>$ret
		echo "--------------------------" >>$ret
	fi
done <$file
cat $ret
rm -f $file $ret

示例二:用sed模拟出tac的功能(倒序输出)。

文件内容

cat mm
1
2
3

解决方法:

sed ‘1!G;h;$!d’mm

ps:1!G第1行不 执行“G”命令,从第2行开始执行。

       $!d,最后一行不删除(保留最后1行)

图解分析过程

P:Pattern Space

H:Hold Space

蓝色:Hold Space中的数据

绿色:Pattern Space中的数据

参考:

《sed and awk 第二版》



展开阅读全文
打赏
0
6 收藏
分享
加载中
更多评论
打赏
0 评论
6 收藏
0
分享
返回顶部
顶部