sed之G、H、g、h使用

sed如何處理數據?
shell

sed在正常狀況下,將處理的行讀入模式空間(pattern space),腳本中的「sed-command(sed命令)」就一條接着一條進行處理,知道腳本執行完畢。而後該行唄輸出,模式(pattern space)被清空;接着,在重複執行剛纔的動做,文件中的新的一行被讀入,直到文件處理完畢。bash

 

什麼是Pattern Space,什麼是Hold Space?app

pattern space至關於車間sed把流內容在這裏處理。spa

hold space至關於倉庫,加工的半成品在這裏臨時儲存。code

PS:你能夠將pattern space當作是一個流水線,全部的動做都是在「流水線」上執行的;而hold space是一個「倉庫」,「流水線」上的東東均可以放到這裏。orm

爲何要使用sed高級命令(G、H、g、h、n、N、x)?it

因爲各類各樣的緣由,好比用戶但願在某個條件下腳本中的某個命令被執行,或者但願模式空間獲得保留以便下一次的處理,都有可能使得sed在處理文件的時候不按照正常的流程來進行。這個時候,sed設置了一些高級命令來知足用戶的要求。class

sed命令:awk

+ g:[address[,address]]g 將hold space中的內容拷貝到pattern space中,原來pattern space裏的內容清除sed

+ 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 第二版》

相關文章
相關標籤/搜索