標籤:sed shell awk linux Regex
設計script時,有時候需要修改指令碼,例如刪除或置換某些關鍵詞。像這種在script執行過程動態修改檔案的做法,稱為流編輯。具有流編輯能力的工具,稱為流編輯器。sed是這方面的強者。另外script執行時可能要製作報表,呈現各欄位資訊,awk完美解決。
一、Regex
Regex是組成“樣式”的基本文法,而“樣式”是運用sed和awk必備的能力。sed和awk相同的運行方式是:只要符合“樣式”的資料行,就對它執行指定的“操作”。
什麼是Regex?
Regex是一種描述的方法,一種小型的語言,可表示某種樣式或若干種樣式的組合,它的威力在於僅需幾個簡單的字元,便可代表許多字串共同的樣子。
1、. 代表任一字元
.a. 代表中間為a,兩邊隨意字元的3個字元。(若要對比.本身需要用\轉義)
2、^ 代表在行首
^abc abd應該出現在行首。"abc,hello"和"hello abc" 前者符合後者不符合
3、$ 代表在尾部
$abc abd應該出現在行尾。"abc,hello"和"hello abc" 後者符合前者不符合
4、[...] 字元集合
[...] 代表字元 串列中的一個字元 [aBc]代表a或B或c。[A-Z]一個大寫[^A-Z]除了大寫之外的一個字元。
5、*出現0個以上
a*c可以是abc、abbc、abbbc、aSJKSKBKc.....
6、\{...\}指定符合的個數
\{3,5\}前邊的字元有3~5個。[a-z]\{3,5\}代表以小寫字母組成的字串,長度為3~5個
7、\(..\)把對比符合的字串暫時儲存起來
a\(..\)b要儲存a、b之間的2個字元,若要提取儲存的字串,可用位置參數,\1代表第一個儲存的字串,\2代表第二個保持的字串。
二、擴充Regex
RE字元 意義與範例
+ 重複1個或1個以上的前一個RE字元
egrep ‘go+d‘ file 搜尋範圍是 god good goood gooood......等
?0個或1個的前一個RE字元
egrep ‘go?d‘ file 搜尋範圍 god good
| 用或(or)的方式找出字串
egrep ‘g(la|oo)d file 搜尋範圍 glad good
()+ 多個重複群組的判別
echo "AxyzxyzxyzxyzC" |egrep ‘A(xyz)C‘ 意思是A開頭,C結尾,中間有一個以上的"xyz"字串的意思
注意: !在正規運算式中不是特殊字元,如果要查包含!與<的字行時, grep ‘[!>]‘ file
[!a-z] 這樣反響選擇是錯誤的,[^a-z] 這樣才是正確的。
格式化列印:printf
三、sed的用法
sed是一種非互動流編輯器,可動態編輯檔案。sed處理的對象是檔案的資料流。sed的工作模式是對比每一資料行,若符合樣式,就執行特定的操作。
sed的文法:sed‘樣式命令‘檔案
意思是如果檔案某一行符合‘樣式‘,就執行指定是的sed命令,如刪除(d)或取代(s)或顯示(p)。
這裡的‘樣式‘使用一對//含括,表示尋找之意。/1,6/第一行到第6行,/a/,/b/含有a到b的行
注意:sed並不會更改原檔案內容。sed的工作方式是讀取檔案內容,經流編輯後,把結果顯示到標準輸出,如想要儲存sed處理結果,要自行運用轉向輸出講結果存成其它檔案。
sed的選項:
sed -n 使用安靜模式,在一般sed模式中,所有來自STDIN的資料一般都會被列出到螢幕上,加上-n後只有經過sed處理的那才一行才會被列出來。
-e 直接在指令模式上進行sed的動作編輯
-f 直接將sed動作寫在一個檔案內,-f filename 則可以執行filename內的sed動作。
-r sed的動作支援延申動作標記法
-i 直接修改檔案讀取的內容.(直接修改原常值內容,小心操作)
動作說明: [n1[,n2]]function
n1,n2不見得會存在,一般代表 選擇進行的動作的行數,舉例來說,如果我的動作是需要在10到20行之間進行的,則10,20[動作行為]
function 有底下這些東西:
a:新增, a的後面可以接字串,而這些字串會在新的一行出現(目前的下一行)
i :插入, i後面可以接字串,而這些字串會在新的一行出現(目前的上一行);
c :取代, c的後面可以接字串,這些字串可以取代 n1,n2 之間的行!
d :刪除,因為是刪除啊,所以 d 後面通常不接任何咚咚;
p :列印,亦即將某個選擇的資料印出。通常 p 會與參數 sed -n 一起運作~
s :取代,可以直接直接進行取代的工作!通常這個 s 的動作可以搭配 正則標記法!例如 1,20s/old/new/g 就是!
sed的文法:
sed ‘s/要取代的字元/新字元/g‘ g表示全域的意思
1、刪除某一段範圍的資料行
sed ‘1,4d‘ file 把第1到第4行資料刪除,剩下的顯示出來。($代表最後一行‘1,$‘)
2、把含有樣式的資料行刪除
sed ‘/ab/d‘ file 把含有ab的所有行刪除。 sed ‘/[0-9]\{3\}/d‘ file 把含有3為數的行刪除。\{3\}表示//要尋找的3個數位字串 sed ‘/^$/d‘ file 刪除空白行
3、把不含樣式的行刪除
sed ‘/ab/!d‘ 不含ab的行刪除,剩下的顯示出來。(或者說把涵ab的行不刪除
4、把含有樣式的資料行顯示出來(但sed預設也顯示不符合的資料行)
sed ‘/ab/p‘ 把含有ab的行顯示出來,不符合的也顯示出來 -n會抑制預設顯示其它行 sed -n ‘/ab/p‘ 只把含ab的行顯示出來。
5、取代
sed -n ‘s/ab/AB/p‘ file 把file中每一行第一個出現ab的字串換位AB,sed -n ‘s/ab/AB/gp‘ file 把file中每行所有的ab都換為AB
sed -n ‘s/ab//p‘ file 把file中每行第一個ab刪除(把ab置換成Null 字元串就是刪除)
sed ‘s/^...//‘ file 把每一行開頭的3個字元刪除,如果^是$,則把每行最後3個字元刪除。
6、取用符合樣式的字串
sed -n ‘s/\(ab\)/\1cd/p‘ file 把每行第一個出現ab的字元換為abcd 。可分解為sed -n ‘s/ \(ab\) / \1cd /p 其中( ) 1之前都用\來轉義,依舊是//模式
7、找到符合樣式的資料後,再進行取代操作
sed -n ‘/AAA/s/ab/AB/p‘ file 找到含有AAA的行後,把第一個出現的ab換成AB(如果是gp,就把每行出現的ab換成AB)
sed -n ‘/aaa/,/bbb/s/123/456/gp‘ file將含有aaa到bbb的那幾行,把所有的123換成456
sed -n ‘2,4s/a/b/p‘ file 由第2行到第4行,把出現的第1個a換成b
例子:
cat /etc/passwd| sed ‘2a hello world‘
在第2行的後邊加一行內容是helloworld,如果a前沒有數字.就在每行後邊另起一行,內容為hello world (如果前邊的話用i)
cat /etc/passwd| sed ‘2i one \ two ‘
在第2行前邊增加2行,內容分別為one、two ,每行之間要用 \(斷行符號) 隔開
cat /etc/passwd | sed ‘2i 1 \
2 \
3 \
4 \
5‘
在第2行前邊增加5行,內容分別是1 2 3 4 5
cat /etc/passwd | sed ‘1c hello world‘ 把第1行內容換為hello world
cat /etc/passwd | sed ‘2,4c hello world‘ 把第2-4行內容換為hello world
cat /etc/passwd | sed -n ‘1p‘ 顯示第1行 如果是 sed -n ‘2,3p‘ 為顯示第2行和第3行。 sed ‘$p‘顯示最後一行
grep -v ‘^$‘ file | grep -v ‘^#‘ 和 egrep -v ‘^$|^#‘ regular_express.txt $代表最後一行去除空白行與行首為 # 的行列
cat /etc/passwd |sed -e ‘1d‘ -e ‘2,3c hello world‘ 把第1行刪除,把第2行和第3行內容換成hello world
注意:
如果sed後跟多個選項,務必使用-e參數
四、awk的用法
awk是一種可以處理資料、產生格式化報表的語言。它的工作方式是讀取資料,將每一行資料視為一條記錄,每筆記錄以欄位分隔符號分成若干欄位,然後輸出各個欄位的值。
awk對每一條記錄,都會套用一個"樣式{操作}",如果該行符合樣式,就執行指定的操作。
樣式或操作之一可以省略。如果只有樣式,表示要顯示符合樣式的行;如果只有操作,表示對每一行資料都執行該項操作。
awk的常用的作用格式:
awk "樣式" 檔案:把符合樣式的資料行顯示出來。
awk ‘{操作}’ 檔案:對每一行都執行{}中的操作。
awk ‘樣式{操作}’對符合樣式的資料行,執行{}中的操作。
awk的幾種用法:
1、awk ‘/root/‘ file
顯示file中root的行
2、awk ‘{print $1,$2}‘ file ","可以省略如果讓兩個字元以空格隔開的話用 awk ‘{print $1 "\t" $2‘
顯示file中每一行的第1個和第2個欄位(預設以空格為分隔字元)
3、awk ‘/ab/{print $1,$2}‘ file
顯示file中有ab的行的第1個和第2個欄位(以空格為分隔字元)
4、awk -F: ‘/^root/{print $2,$3}‘ file
以":"為分隔字元,把以root開頭的行中的第2個和第3個字元顯示出來。
5、awk -F: ‘BEGIN{OFS="++++"}/^root/{print $1,$2,$3}‘ /etc/passwd
把passwd中,以":"為分隔字元找出首行為root的行,並顯示前3個欄位,並且欄位之間以+++隔開
執行個體:
變數名稱代表意義
NF每一行$0擁有的欄位總數(預設以空格或Tab為分隔字元)
NR目前awk所處理的是第幾行資料
FS目前的分隔字元,預設是空格鍵
[[email protected] ~]# cat 1a2a3a4a5ab2b3b4b5bc2c3c4c5c[[email protected] ~]# cat 1|awk ‘{print $1 "\t 行:" NR "\t 該行總欄位:" NF}‘a 行:1 該行總欄位:5b 行:2 該行總欄位:5c 行:3 該行總欄位:5查閱passwd第三欄資料小於10的資料的行,並且僅列出帳號和第三欄。cat /etc/passwd|awk ‘{FS=":"}$3<10 {print $1 "\t" $3}‘ root:x:0:0:root:/root:/bin/bashbin1daemon2...mail8
上邊第一行會全部顯示出來,這是因為我們讀入第一行的時候,那些變數 $1, $2..預設還是以空格鍵為分隔的,所以雖然我們定義了 FS=":" 了, 但是卻僅能在第二行後才開始生效。
那麼怎麼辦呢?我們可以預先設定 awk 的變數啊! 利用 BEGIN 這個關鍵詞!這樣做:cat /etc/passwd|awk ‘BEGIN{FS=":"}$3<10 {print $1 "\t" $3}‘
顯示ip地址
ifconfig |grep ‘inet addr‘|grep Bcast|awk ‘{print $2}‘|awk -F: ‘{print $2}‘
顯示網路名稱
cat /proc/net/dev |awk -F: ‘/eth.:|sit.:|wlan.:|ppp.:/{print $1}‘
sed與awk可以單獨寫出一本書,實在很強大,本篇只介紹最簡單的用法。
這些都是讀書筆記,接下來我們真正進入Shell實戰!
本文出自 “Welcome To Linux World” 部落格,請務必保留此出處http://linuxnote.blog.51cto.com/9876511/1641278
Linux Shell之十 sed與awk