在linux中,主要通過sed命令來替換文本,通過Regex匹配出的命令,可以用sed來靈活的替換掉,極大的節省了工作量。可以說,sed是shell指令碼裡替換的最主要力量,也是shell指令碼裡用的最多的命令之一,sed是基於行的編譯器,也就是說,它會將匹配到的內容的行列印出來,而且sed有自己的模式空間(記憶體),也就是說sed並不會改變原檔案的內容,但是sed -i 可以直接修改原檔案(此功能慎用,很容易造成損失)
sed的用法格式:
sed [option] /PATTERN/COMMAND files
sed [option] ADDR,ADDR/COMMAND files
-n //避免沒有被匹配的行顯示
-i //直接修改原檔案
另外介紹三個基本Regex,可以配合sed來匹配單詞
\<或\b //錨定詞首 [^ ] //取反,除...之外的一個字元
\>或\b //錨定詞尾
##一個簡單的例子來說明sed的用法:
sed 1,3p /proc/cpuinfo
這條命令將cpuinfo的內容前三行列印兩次,如果只要顯示前三行,則加 -n 選項,這裡的1,3指第一到三行,p是列印的意思。
##擴充幾個sed的command:
p 列印 /i 在匹配的內容之前插入
/d 刪除 /a 在匹配的內容之後插入
s 替換 /g 全域替換
同時sed也可以使用Regex:
例如:
sed "/^model/a\#This is my cpu." /proc/cpuinfo
#看到^了嗎?這個命令的意思是在model之後插入#This is my cpu. 注意是model這行後面的一行。
下面介紹替換,替換的模式 s/要尋找的內容/要替換成的內容/command
例如:
sed ‘1,$s/yes/YES/' /proc/cpuinfo
#將/proc/cpuinfo裡從1到最後一行裡的yes替換成YES。
#1,$指從第一行到最後一行 $在這裡匹配最後一行,$-2倒數第二行,以此類推。
# 也可以使用/g全域替換,即合格全部替換掉
好了,關於sed的幾個練習:
sed練習
1、將/etc/inittab檔案中以id開頭後面跟了兩個冒號且兩個冒號間有一個數位那一行中的那兩個冒號間的數字改為3;
2、將/etc/passwd檔案中以n開頭的所有單詞的詞首字母改為大寫;
3、在/proc/meminfo檔案中所有以HugePages開頭的行後面添加“# For performancing”一個新行;
4、刪除/etc/inittab檔案中所有以#開頭,或者以一些空白字元後跟一個#開頭的行,並且將所有以一個空格後跟一個數字結尾的行中的那個行尾的數字改為0;
答案:1. sed s@^id:[0-9]:@id:3:@g /etc/inittab
#這裡的@也是替代符號,當要替換的文本是路徑時,這個技巧很好用。
2. sed '1,$s/\bn/N/pg' /etc/passwd
3. sed "/HugePages/a\# For performancing" /proc/meminfo
4. sed -e '/^[[:space:]]*#.*/d' /etc/inittab -e "s/[[:space:]][0-9]$/ 0/g" /etc/inittab
#這裡使用了-e 選項,處理兩條sed命令 因為文本的開頭都有一個Null 字元,所以^[[:space:]]*#匹配第一個要求,*代表0到任意個
————————————————————————————————————————————————————————————————————————————————
tr命令可以方便的將指定字元替換成別的字元,例如小寫字母替換成大寫字母,而sed是處理行的,和tr配合使用,可以方便快速的替換行裡的字元。
例如:echo abCD | tr ’ab‘ ’AB‘ //將ab替換為AB
tr有一個比較常用的選項 -d, –delete 刪除集合1中的字元而不是轉換
eco "banana" | tr -d 'a'
#一個sed和tr的指令碼
寫一個指令碼:
1、將/var/目錄下所有檔案的檔案名稱的首字母和尾字母顯示時改為大寫;
#!/bin/bash#: Title:lsvar #: Synopsis: #: Date:2011-07-26 23:35:27#: Version: 1.0#: Author: Dean #: Options:for FILE in `ls /var`; do FLITER=`echo "$FILE" | sed '1,$s/\([a-zA-Z]\).*/\1/g' | tr 'a-z' 'A-Z'` LLITER=`echo "$FILE" | sed '1,$s/.*\([a-zA-Z]\)/\1/g' | tr 'a-z' 'A-Z'` echo "$FILE" | sed "s/[a-zA-Z]\(.*\)[a-zA-Z]/$FLITER\1$LLITER/g"done