設計script時,有時候需要修改腳本,例如删除或置換某些關鍵詞。像這種在script執行過程動态修改檔案的做法,稱為流編輯。具有流編輯能力的工具,稱為流編輯器。sed是這方面的強者。另外script執行時可能要制作報表,呈現各字段資訊,awk完美解決。
一、正規表達式
正規表達式是組成“樣式”的基本文法,而“樣式”是運用sed和awk必備的能力。sed和awk相同的運作方式是:隻要符合“樣式”的資料行,就對它執行指定的“操作”。
什麼是正規表達式?
正規表達式是一種描述的方法,一種小型的語言,可表示某種樣式或若幹種樣式的組合,它的威力在于僅需幾個簡單的字元,便可代表許多字元串共同的樣子。
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代表第二個保持的字元串。
二、擴充正規表達式
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置換成空字元串就是删除)
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目前的分隔符,預設是空格鍵
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<code>[root@centos ~]</code><code># cat 1</code>
<code>a2a3a4a5a</code>
<code>b2b3b4b5b</code>
<code>c2c3c4c5c</code>
<code>[root@centos ~]</code><code># cat 1|awk '{print $1 "\t 行:" NR "\t 該行總字段:" NF}'</code>
<code>a 行:1 該行總字段:5</code>
<code>b 行:2 該行總字段:5</code>
<code>c 行:3 該行總字段:5</code>
<code>查閱</code><code>passwd</code><code>第三欄資料小于10的資料的行,并且僅列出賬号和第三欄。</code>
<code>cat</code> <code>/etc/passwd</code><code>|</code><code>awk</code> <code>'{FS=":"}$3<10 {print $1 "\t" $3}'</code>
<code>root:x:0:0:root:</code><code>/root</code><code>:</code><code>/bin/bash</code>
<code>bin1</code>
<code>daemon2</code>
<code>...</code>
<code>mail8</code>
上邊第一行會全部顯示出來,這是因為我們讀入第一行的時候,那些變數 $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實戰!
本文轉自Jacken_yang 51CTO部落格,原文連結:http://blog.51cto.com/linuxnote/1641278,如需轉載請自行聯系原作者