目錄
1. 將模式空間和保持空間的內容互換并打印
2. 將保持空間的內容交換回模式空間
3. 使用保持空間保存狀態信息
4. 交換模式空間與保持空間隔行匹配
? ? ? ? sed 有兩個內置的緩存空間:
- 模式空間:該空間是 sed 內置的一個緩沖區,是 sed 執行的正常流程中,暫存當前處理行的空間。每處理完一行都會清空模式空間后再讀取下一行。模式空間初始為空。
- 保持空間:保持空間是另外一個緩沖區,用來存放臨時數據,以便在后續處理中使用。與模式空間不同,保持空間的內容不會在循環中被刪除。不能在保持空間上執行普通的 sed 命令。保持空間初始為一個換行符。
? ? ? ? sed 可以用 x(Exchange)命令交換模式空間和保持空間的內容。該命令通常和其它 sed 命令配合使用。以下用一些例子說明 x 命令的執行邏輯。
1. 將模式空間和保持空間的內容互換并打印
#echo -e "line1\nline2" | sed -n -e 'x;p'line1
#
? ? ? ? 在這個例子中,x 命令交換了模式空間和保持空間的內容;p 命令打印模式空間的內容。完整的執行流程如下表所示。
循環次數 | 模式空間 | 保持空間 | 操作 |
1 | line1 \n 空 | \n line1 line1 | x => p \n => |
2 | line2 line1 | line1 line2 | x => p line1 |
2. 將保持空間的內容交換回模式空間
#echo -e "line1\nline2" | sed -n -e 'x;x;p'
line1
line2
#
? ? ? ? 在這個例子中,連續使用了兩次 x 命令,第一次將內容交換到保持空間,第二次又將保持空間的內容交換回模式空間。結果是每一行都沒有改變,仍然為原來的內容。完整的執行流程如下表所示。
循環次數 | 模式空間 | 保持空間 | 操作 |
1 | line1 \n line1 空 | \n line1 \n \n | x => x => p line1 => |
2 | line2 \n line2 | \n line2 \n | x => x => p line2 |
3. 使用保持空間保存狀態信息
#echo -e "line1\nline2\nline3" | sed -n -e '/line2/!x;//!d;x;p'
line1
line3
#
? ? ? ? 在這個例子中,對于不包含 line2 的行,交換到保持空間,否則保持模式空間不變;然后刪除模式空間中的非空行;之后再次交換模式空間與保持空間的內容;最后打印模式空間的內容。結果是包含 line2 的行被刪除,其它行沒有任何變化。完整的執行流程如下表所示。
循環次數 | 模式空間 | 保持空間 | 操作 |
1 | line1 \n 空 line1 空 | \n line1 line1 空 空 | x => d => x => p line1 => |
2 | line2 空 空 空 | 空 空 空 空 | d => x => p => |
3 | line3 空 line3 | 空 line3 空 | x => x => p line3 |
4. 交換模式空間與保持空間隔行匹配
? ? ? ? 示例文本 empnametitle.txt 的內容如下:
John Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager
? ? ? ? 每個記錄對應姓名和職位兩行,比如 John Doe 的職位是 CEO。下面的命令打印職位是 Manager 的員工姓名。
#sed -n -e '{x;n}' -e '/Manager/{x;p}' empnametitle.txt
Jason Smith
Jane Miller
#
? ? ? ? '{x;n}' 是將模式空間交換到保持空間,然后讀取模式空間的下一行。這時達到的效果是將當前行保存到保持空間,將下一行讀到模式空間內。即實現了奇數行和偶數行的分離,職位讀取到模式空間,姓名讀取到保持空間。
?
? ? ? ? '/Manager/{x;p}' 的作用是如果模式空間里含有關鍵字 Manager,則將保持空間交換回模式空間,并打印出模式空間的內容,即員工姓名。
? ? ? ? 完整的執行流程如下表所示。
循環次數 | 模式空間 | 保持空間 | 操作 |
1 | John Doe \n CEO 空 | \n John Doe John Doe John Doe | x => n => |
2 | Jason Smith John Doe IT Manager Jason Smith 空 | John Doe Jason Smith Jason Smith IT Manager IT Manager | x => n => x => p Jason Smith => |
3 | Raj Reddy IT Manager Sysadmin 空 | IT Manager Raj Reddy Raj Reddy Raj Reddy | x => n => |
4 | Anand Ram Raj Reddy Developer 空 | Raj Reddy Anand Ram Anand Ram Anand Ram | x => n => |
5 | Jane Miller Anand Ram Sales Manager Jane Miller | Anand Ram Jane Miller Jane Miller Sales Manager | x => n => x => p Jane Miller |
? ? ? ? 注意:上例中的命令順序是先 x 后 n,如果調換兩個命令的順序,將產生不同的結果。
#sed -n -e '{n;x}' -e '/Manager/{x;p}' empnametitle.txt
Sysadmin
Developer
Sales Manager
#
? ? ? ? 完整的執行流程如下表所示。
循環次數 | 模式空間 | 保持空間 | 操作 |
1 | John Doe CEO \n 空 | \n \n CEO CEO | n => x => |
2 | Jason Smith IT Manager CEO 空 | CEO CEO IT Manager IT Manager | n => x => |
3 | Raj Reddy Sysadmin IT Manager Sysadmin 空 | IT Manager IT Manager Sysadmin IT Manager IT Manager | n => x => x => p Sysadmin => |
4 | Anand Ram Developer IT Manager Developer 空 | IT Manager IT Manager Developer IT Manager IT Manager | n => x => x => p Developer => |
5 | Jane Miller Sales Manager IT Manager Sales Manager | IT Manager IT Manager Sales Manager IT Manager | n => x => x => p Sales Manager |