寫在前面
本篇是個人學習整理筆記而得。
原書:Sed and Awk 101 Hacks -中文版
引用書結尾的一句話:
Knowledge is not one man’s Entity
sed 附加命令
1. sed 附加命令
### 語法
sed '[address] a the-line-to-append' input-file
### 在指定行后添加一行,第2行后添加一行203
sed '2 a 203,Jack,Engineer' employee.txt
### 在匹配行后添加多行
sed '/Jason/a 203,Jack Johnson,Engineer\n204,Mark Smith,Sales Engineer' employee.txt
2. 插入 i 命令
### 語法
sed '[address] i the-line-to-insert' input-file
### 在指定行前插入一行,在第2行之前添加一行203
sed '2 i 203,Jack,Engineer' employee.txt
### 插入多行,用法同上
3. 修改 c 命令
### 語法
sed '[address] c the-line-to-insert' input-file
### 用新行取代舊行,可以與 s 命令等價使用
sed '2 c 202,Jack,Engineer' employee.txt
sed '2s/.*/202,Jack,Engineer/' employee.txt
### 可以用多行取代一行,用法同上
4. 打印不可見字符 l 命令
sed -n 'l' dos.txt
### l 命令后指定數(shù)字,會在第n個字符使用一個不可見的自動折行
sed -n 'l 20' employee.txt
5. 打印行號 = 命令
### 打印所有行的行號
sed '=' employee.txt
### 打印指定行的行號
sed '1,3=' employee.txt
### 打印匹配到行的行號
sed '/Jane/=' employee.txt
### 配合-n,打印總行數(shù)(最后一行的行號)
sed -n '$=' employee.txt
6. 轉換字符 y 命令
### 命令y可以根據(jù)對應位置轉換字符
# 常用于,大小寫轉換
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' employee.txt
7. 操作多個文件
sed -n '/root/p' /etc/passwd /etc/group
8. sed退出 q 命令
### 在指定行,退出
sed '3 q' employee.txt
### 匹配到行,退出
sed '/Manager/q' employee.txt
9. 讀取文件數(shù)據(jù) r 命令
### r命令會讀取另一個文件的內容,并在指定的位置打印出來# 在指定到的行,打印另一個文件內容
sed '$r log.txt' employee.txt
### 在匹配到的行,打印另一個文件的內容
sed '/Raj/r log.txt' employee.txt
10. 選項 和 命令
### -l選項用于指定行的長度(需要配合l命令使用)
sed -nl 20 'l' employee.txt
### l命令也可以單獨使用指定行長度
sed -n 'l20' employee.txt
### 容易混淆的還有
# -i 選項,直接修改原文件 <> i命令用于插入數(shù)據(jù)
# -n 選項,屏蔽默認輸出 <> n命令打印模式空間
sed 保持空間和模式空間
1. 概念
sed 有兩個內置的存儲空間:
- 模式空間:
如你所知,模式空間用于 sed 執(zhí)行的正常流程中。該空間 sed 內置的一個緩沖區(qū),用來存放、修改從輸入文件讀取的內容。- 保持空間:
保持空間是另外一個緩沖區(qū),用來存放臨時數(shù)據(jù)。sed 可以在保持空間和模式空間交換數(shù)據(jù),但是不能在保持空間上執(zhí)行普通的 sed 命令。我們已經(jīng)討論過,每次循環(huán)讀取數(shù)據(jù)過程中,模式空間的內容都會被清空,然而保持空間的內容。則保持不變,不會在循環(huán)中被刪除。
2. 交換 x 命令
命令x(exchange) 用于交換模式空間和保持空間的內容
3. 模式空間復制到保持空間 h命令
命令h(hold), 與x命令不同在于不會改變模式空間當前內容,保持空間的內容會被覆蓋
( cat << EOF
John
Doe
CEO
Jason Smith
IT Manager
Raj Reddy
Sysadmin
Anand Ram
Developer
Jane Miller
Sales Manager
EOF
) > empname.txt
]# sed -n -e '/Manager/!h' -e'/Manager/{x;p}' empname.txt
Jason Smith
Jane Miller
######################################################################################
# 逐行的讀取,'/Manager/!h'表示遇到不包含Manager關鍵字的行,就復制到保持空間(注意是覆蓋了保
# 持空間原有的內容),'/Manager/{x;p}'表示遇到包含Manager關鍵字的一行,就與保持空間交換并打印
# 交換后的模式空間內容(打印內容就是上一行,也就是Manager的姓名)。
######################################################################################
4. 模式空間追加到保持空間 H命令
### 同時管理者姓名和職位
]# sed -n '/Manager/!h;/Manager/{H;x;p}' empname.txt
Jason Smith
IT Manager
Jane Miller
Sales Manager
#### 格式化為一行
]# sed -n '/Manager/!h;/Manager/{H;x;s/\n/: /p}' empname.txt
Jason Smith: IT Manager
Jane Miller: Sales Manager
5. 保持空間復制到模式空間 g命令
### 打印管理者的姓名
]# sed -n '/Manager/!h;/Manager/{g;p}' empname.txt
Jason Smith
Jane Miller
6. 保持空間追加到模式空間 G命令
### 格式打印管理者及其職位
]# sed -n '/Manager/!h;/Manager/{x;G;s/\n/: /p}' empname.txt
Jason Smith: IT Manager
Jane Miller: Sales Manager
]#
######################################################################################
# m代表模式空間,h表示保持空間
# 先交換(m中為姓名,h為職位),再h追加到m中(m中姓名和職位分行排列),最后替換換行符
######################################################################################
7. 讀取下一行數(shù)據(jù)附加到模式空間 N命令
### n打印當前模式空間內容并清空,讀取下一行到模式空間### N不打印不清空,讀取下一行追加到模式空間
]# sed -n 'N;s/\n/: /p' empname.txt
John: Doe
CEO: Jason Smith
IT Manager: Raj Reddy
Sysadmin: Anand Ram
Developer: Jane Miller
8. 打印多行模式中的第一行 P命令
### p打印模式空間的內容### P打印模式空間的第一行
]# sed -n 'N;/Manager/P' empname.txt
Jason Smith
Jane Miller
]# sed -n 'N;/Manager/l' empname.txt
Jason Smith\nIT Manager$
Jane Miller\nSales Manager$
]#
######################################################################################
# 'N' 將下一行追加到當前行(相當于每兩行合并成一行,來執(zhí)行第二條命令,并沒有刪掉換行符),
# '/Manager/P' 會匹配是否包含Manager, 如果包含P打印至換行符'\n'(也就是管理者姓名)
######################################################################################
9. 刪除多行模式中的第一行 D命令
- d 刪除模式空間的內容,然后讀取下一行到空間,并且忽略后邊的命令,進行新一次的循環(huán)
- D 刪除模式空間的第一行,不讀取下一行,忽略后邊的命令,在當前空間從頭執(zhí)行命令
10. 命令b 和 :label標簽 和 t命令
### :label 定義一個標簽### b label 會跳轉到label標簽執(zhí)行其之后的命令# 格式打印,并在管理者前加*號
]# sed -n '{
> N;
> s/\n/: /
> /Manager/!b end
> s/^/*/
> :end
> p}' empname.txt
John: CEO
*Jason Smith: IT Manager
Raj Reddy: Sysadmin
Anand Ram: Developer
*Jane Miller: Sales Manager
]#
######################################################################################
# 這里定義了一個end標簽,后邊接了一個命令p
# 第三行匹配Manager關鍵字,不匹配的直接跳轉到end標簽之后
# 匹配的會先執(zhí)行替換開頭為*的操作,然后再執(zhí)行后邊的命令
# t label 如果前面命令執(zhí)行成功,會跳轉到 label標簽往下執(zhí)行后續(xù)命令### 否則,按正常流程執(zhí)行
######################################################################################
]# sed -n '{
N;
s/\n/: /;
:repeat;
/Manager/s/^/*/
/\*\*\*/!t repeat
p }' empname.txt
John: CEO
***Jason Smith: IT Manager
Raj Reddy: Sysadmin
Anand Ram: Developer
***Jane Miller: Sales Manager
]#
######################################################################################
# 定義了一個repeat標簽
# /Manager/s/^/*/ 是循環(huán)塊,給包含Manager行前加*號# /\*\*\*/!t repeat 匹配是否包含三個*號的行,不包含跳轉回repeat標簽處# 包含了的話,往下執(zhí)行
######################################################################################