一正則表達式
sed: stream editor, 流編輯器;
awk(gawk):文本格式化工具,報告生成器express
二 sed stream editor for filtering and transforming textvim
sed [OPTION]... {script-only-if-no-other-script} [input-file]...數組
工做機制:每次讀取一行文本至「模式空間(pattern space)」中,在模式空間中完成處理;將處理結果輸出至標準輸出設備;bash
sed 不加-i參數,不會修改源文件,只會顯示修改後的內容在輸出設備app
命令參數tcp
-r 支持擴展正則表達式;
-n 靜默模式;
-e script1 -e script2 -e script3 指定多腳本運行;
-f /path/to/script_file 從指定的文件中讀取腳本並運行;
-i 直接修改源文件;編輯器
基本正則表達式元字符:
字符匹配:., [], [^]
次數匹配:*, \?, \+, \{m,n\}, \{n\}
位置錨定:^, $, \<, \>
分組及引用:\(\), \1, \2, ...
多選一:a|b|cide
地址定界:
# 指定行
$ 最後一行
/regexp/ 任何可以被regexp所匹配到的行
\%regexp% 同上,只不過換做%爲regexp邊界符
/regexp/| 匹配時忽略字符大小寫
\%regexp%| 匹配時忽略字符大小寫,只不過換做%爲regexp邊界符函數
startline,endline:
#,/regexp/ 從#行開始,到第一次被/regexp/所匹配到的行結束,中間的全部行;
#,#
/regexp1/,/regexp2/ 從第一次被/regexp1/匹配到的行開始,到第一次被/regexp2/匹配到的行結束,中間的全部行;
#,+n 從#行開始,一直到向下的n行;
first~step 指定起始行,以及步長; 1~2,2~2
sed的編輯命令
d 刪除模式空間中的行
= 顯示行號
a \text 附加text
i \text 插入text,支持\n實現多行插入
c \text 用text替換匹配到的行
p 打印模式空間中的行
s/regexp/replacement/ 替換由regexp所匹配到的內容爲replacement
g 全局替換
w /path/to/somefile 把指定的內容另存至/path/to/somefile路徑所指定的文件中
r /path/from/somefile 在文件的指定位置插入另外一個文件的全部內容,完成文件合併
[root@localhost ~]# echo Sunday | sed 's/day/night/' #替換Sunday中的day爲night Sunnight
[root@localhost test]# vim xxx.txt 1 2 3 4 5
刪除
[root@localhost test]# sed "1d" xxx.txt #刪除第一行 2 3 4 5 [root@localhost test]# sed "$d" xxx.txt #刪除最後一行 1 2 3 4 5 [root@localhost test]# sed '$d' xxx.txt #刪除最後一行 1 2 3 4 [root@localhost test]# sed '1,3d' xxx.txt #刪除1-3 行 4 5 [root@localhost test]# sed '3,$d' xxx.txt #刪除3到最後一行 1 2
附加
[root@localhost test]# sed '1a test add' xxx.txt #在第一行後面插入test add 1 test add 2 3 4 5 [root@localhost test]# sed '1,3a test add' xxx.txt #在第一行到第三行後面都插入test add 1 test add 2 test add 3 test add 4 5 [root@localhost test]# sed '1,3a test1 \ntest2' xxx.txt #在第一行到第三行後面都插入test1 test2兩行,使用換行符\n 1 test1 test2 2 test1 test2 3 test1 test2 4 5 [root@localhost test]# sed '$a xxx' xxx.txt #在最後一行插入xxx 1 2 3 4 5 xxx
替換
[root@localhost test]# sed '1c test' xxx.txt #將第一行替換爲test test 2 3 4 5 [root@localhost test]# sed '1,3c test' xxx.txt #將1-3行替換爲test test 4 5 [root@localhost test]# sed '/2/p' xxx.txt #將匹配到的2 打印模式空間中的行 1 2 2 3 4 5 [root@localhost test]# sed 's/2/pp/g' xxx.txt #將匹配到的2 替換爲pp 1 pp 3 4 5
刪除/boot/grub/grub.conf文件中全部行的行首的空白字符;
[root@localhost test]# cat /boot/grub/grub.conf # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS 6 (2.6.32-573.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-573.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-573.el6.x86_64.img [root@localhost test]# sed 's/^[[:space:]]\+//' /boot/grub/grub.conf # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS 6 (2.6.32-573.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-573.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-573.el6.x86_64.img
刪除/etc/fstab文件中全部以#開頭,後跟至少一個空白字符的行的行首的#和空白字符;
[root@localhost test]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Mon Sep 21 18:38:21 2015 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 UUID=8f13d755-9ea5-4250-91d7-e7bb313381d8 /boot ext4 defaults 1 2 /dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2 /dev/mapper/VolGroup-lv_swap swap swap defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 [root@localhost test]# sed 's/^#[[:space:]]\+//' /etc/fstab # /etc/fstab Created by anaconda on Mon Sep 21 18:38:21 2015 # Accessible filesystems, by reference, are maintained under '/dev/disk' See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 UUID=8f13d755-9ea5-4250-91d7-e7bb313381d8 /boot ext4 defaults 1 2 /dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2 /dev/mapper/VolGroup-lv_swap swap swap defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0
把/etc/fstab文件的奇數行另存爲/tmp/fstab.3;
[root@localhost test]# sed '1~2w /tmp/fstab.3' /etc/fstab # # /etc/fstab # Created by anaconda on Mon Sep 21 18:38:21 2015 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 UUID=8f13d755-9ea5-4250-91d7-e7bb313381d8 /boot ext4 defaults 1 2 /dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2 /dev/mapper/VolGroup-lv_swap swap swap defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 [root@localhost test]# cat /tmp/fstab.3 # /etc/fstab # # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 /dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2 tmpfs /dev/shm tmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0
echo一個文件路徑給sed命令,取出其基名;進一步地,取出其路徑名
[root@localhost test]# echo "/etc/sysconfig/network-scripts/" | sed 's@^.*/\([^/]\+\)/\?$@\1@' network-scripts [root@localhost test]# echo "/etc/sysconfig/network-scripts/" | sed 's@[^/]\+/\?$@@' /etc/sysconfig/
高級命令:
h 用模式空間中的內容覆蓋保持空間的內容;
H 把模式空間中的內容追加至保持空間中內容的後面;
g 從保持空間中取到其內容,並將其覆蓋模式空間中的內容;
G 從保持空間中取到其內容,並將其追加在模式空間中的內容的後面;
x 把保持空間和模式空間中的進行交換;
n 讀取匹配到的行的下一行至模式空間;(會覆蓋模式空間中的原有內容);
N 讀取匹配到的行的下一行至模式空間,追加在模式空間中原有內容的後面;
d 刪除模式空間中的內容;
D 刪除多行模式空間中的首行;
注意:命令功能可以使用!取反;分號可用於分隔腳本;
示例:
在文件中的每行後方添加空白行
[root@localhost test]# cat /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]# sed 'G' /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]#
保留最後一行
[root@localhost test]# cat /etc/fstab # # /etc/fstab # Created by anaconda on Mon Sep 21 18:38:21 2015 # # Accessible filesystems, by reference, are maintained under '/dev/disk' # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info # /dev/mapper/VolGroup-lv_root / ext4 defaults 1 1 UUID=8f13d755-9ea5-4250-91d7-e7bb313381d8 /boot ext4 defaults 1 2 /dev/mapper/VolGroup-lv_home /home ext4 defaults 1 2 /dev/mapper/VolGroup-lv_swap swap swap defaults 0 0 tmpfs /dev/shm tmpfs defaults 0 0 devpts /dev/pts devpts gid=5,mode=620 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 [root@localhost test]# sed '$!d' /etc/fstab proc /proc proc defaults 0 0
保證指定的文件每一行後方有且只有一個空白行
[root@localhost test]# cat /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]# sed '/^$/d;G' /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]#
保留奇數行
[root@localhost test]# cat /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]# sed 'n;d' /etc/issue CentOS release 6.7 (Final) [root@localhost test]#
反向輸出一個文件
[root@localhost test]# cat /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]# sed -n '1!G;h;$p' /etc/issue Kernel \r on an \m CentOS release 6.7 (Final)
保留文件的最後兩行
[root@localhost test]# cat /etc/issue CentOS release 6.7 (Final) Kernel \r on an \m [root@localhost test]# sed '$!N;$!D' /etc/issue Kernel \r on an \m [root@localhost test]#
三 awk gawk - pattern scanning and processing language
Gnu AWK, gawk
awk [options] 'program' file file ...
awk [options] 'PATTERN{action}' file file ...
gawk [ POSIX or GNU style options ] -f program-file [ -- ] file ...
gawk [ POSIX or GNU style options ] [ -- ] program-text file ...
-F CHAR:輸入分隔符
一、awk的輸出
print item1, item2,...
要點:
(1) 各項目之間使用逗號分隔,而輸出時則使用輸出分隔符分隔;
(2) 輸出的各item能夠字符串或數值、當前記錄的字段、變量或awk的表達式;數值會被隱式轉換爲字符串後輸出;
(3) print後面item若是省略,至關於print $0;輸出空白,使用pirnt "";
二、awk的變量
內置變量,自定義變量
2.1 內置變量
FS Field Seperator, 輸入時的字段分隔符
# awk 'BEGIN{FS=":"}{print $1,$7}' /etc/passwd
RS Record Seperator, 輸入行分隔符
OFS Output Field Seperator, 輸出時的字段分隔符;
ORS Outpput Row Seperator, 輸出時的行分隔符;
NF Numbers of Field,字段數
NR Numbers of Record, 行數;全部文件的一併計數;
FNR 行數;各文件分別計數;
ARGV 數組,保存命令自己這個字符,awk '{print $0}' 1.txt 2.txt,意味着ARGV[0]保存awk,
ARGC 保存awk命令中參數的個數;
FILENAME awk正在處理的當前文件的名稱;
2.2 可自定義變量
-v var_name=VALUE
變量名區分字符大小寫;
(1) 能夠program中定義變量;
(2) 能夠命令行中經過-v選項自定義變量;
三、awk的printf命令
命令的使用格式:printf format, item1, item2,...
要點:
(1) 要指定format;
(2) 不會自動換行;如需換行則須要給出\n
(3) format用於爲後面的每一個item指定其輸出格式;
format格式的指示符都%開頭,後跟一個字符:
%c 顯示字符的ASCII碼;
%d, %i 十進制整數;
%e, %E 科學計數法顯示數值;
%f 顯示浮點數;
%g, %G 以科學計數法格式或浮點數格式顯示數值;
%s 顯示字符串;
%u 顯示無符號整數;
%% 顯示%自身;
修飾符:
# 顯示寬度
- 左對齊
+ 顯示數值的符號
.# 取值精度
四、awk輸出重定向
print items > output-file
print items >> output-file
print items | command
特殊文件描述符:
/dev/stdin 標準輸入
/dev/stdout 標準輸出
/dev/stderr 錯誤輸出
五、awk的操做符
算術操做符:
x+y
x-y
x*y
x/y
x**y, x^y
x%y
-x 負值
+x 轉換爲數值
字符串操做符 鏈接
賦值操做符:
=
+=
-=
*=
/=
%=
^=
**=
++
--
若是模式自身是=號,要寫爲/=/
比較操做符:
<
<=
>
>=
==
!=
~ 模式匹配,左邊的字符串可以被右邊的模式所匹配爲真,不然爲假;
!~:
邏輯操做符:
&& 與
|| 或
條件表達式:
selector?if-true-expression:if-false-expression
# awk -F: '{$3>=1000?utype="common user":utype="admin or system user";print $1,"is",utype}' /etc/passwd
函數調用:
function_name(argu1,argu2)
六、模式
(1) Regexp: 格式爲/PATTERN/
僅處理被/PATTERN/匹配到的行;
(2) Expression: 表達式,其結果爲非0或非空字符串時知足條件;
僅處理知足條件的行;
(3) Ranges: 行範圍,此前地址定界,
NR
僅處理範圍內的行
(4) BEGIN/END: 特殊模式,僅在awk命令的program運行以前(BEGIN)或運行以後(END)執行一次;
(5) Empty:空模式,匹配任意行;
七、經常使用的action
(1) Expressions
(2) Control statements
(3) Compound statements
(4) input statements
(5) output statements
八、控制語句
8.1 if-else
格式:if (condition) {then body} else {else body}
# awk -F: '{if ($3>=500) {print $1,"is a common user"} else {print $1, "is an admin or system user"}}' /etc/passwd
# awk '{if (NF>=8) {print}}' /etc/inittab
8.2 while
格式:while (condition) {while body}
# awk '{i=1; while (i<=NF){printf "%s ",$i;i+=2};print ""}' /etc/inittab
# awk '{i=1; while (i<=NF){if (length($i)>=6) {print $i}; i++}}' /etc/inittab
length()函數:取字符串的長度
8.3 do-while循環
格式:do {do-while body} while (condition)
8.4 for循環
格式:for (variable assignment; condition; iteration process) {for body}
# awk '{for (i=1;i<=NF;i+=2){printf "%s ",$i};print ""}' /etc/inittab
# awk '{for (i=1;i<=NF;i++){if (length($i)>=6) print $i}}' /etc/inittab
for循環可用來遍歷數組元素:
語法:for (i in array) {for body}
8.5 case語句
語法:switch (expression) {case VALUE or /RGEEXP/: statement1;... default: stementN}
8.6 循環控制
break
continue
8.7 next
提早結束對本行的處理進而提早進入下一行的處理;
# awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
# awk -F: '{if(NR%2==0) next; print NR,$1}' /etc/passwd
九、數組
傳統數組:Index編號從1開始;
關聯數組:
array[index-expression]
index-expression: 可使用任意字符串; 若是某數組元素事先不存在,那麼在引用時,awk會自動建立此元素並將其初始化爲空串;所以,要判斷某數組是否存在某元素,必須使用「index in array」這種格式;
A[first]="hello awk"
print A[second]
要遍歷數組中的每個元素,須要使用以下特殊結構:
for (var in array) {for body}
其var會遍歷array的索引;
state[LISTEN]++
state[ESTABLISHED]++
# netstat -tan | awk '/^tcp/{++state[$NF]}END{for (s in state) {print s,state[s]}}'
# awk '{ip[$1]++}END{for (i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
刪除數組元素:
delete array[index]
十、awk的內置函數
split(string,array[,fieldsep[,seps]]):
功能:將string表示的字符串以fieldsep爲分隔符進行切片,並切片後的結果保存至array爲名的數組中;數組下標從1開始;
root:x:0:0::/root:/bin/bash
user[1]="root", user[2]
此函數有返回值,返回值爲切片後的元素的個數
# netstat -tn | awk '/^tcp/{lens=split($5,client,":");ip[client[1]]++}END{for (i in ip) print i,ip[i]}'
length(string)
功能:返回給定字串的長度
substr(string,start[,length]) 功能:從string中取子串,從start爲起始位置爲取length長度的子串;