1. 程式人生 > >第9章 正則 擴展

第9章 正則 擴展

不包含 表達 某個字段 變量 轉換 多行 同時 goto ash

//擴展一//
第14章 正則表達式 http://www.apelearn.com/study_v2/chapter14.html
grep
語法: grep [-cinvABC] ‘word‘ filename
-c :打印符合要求的行數
-i :忽略大小寫
-n :在輸出符合要求的行的同時連同行號一起輸出
-v :打印不符合要求的行
-A :後跟一個數字(有無空格都可以),例如 –A2則表示打印符合要求的行以及下面兩行
-B :後跟一個數字,例如 –B2 則表示打印符合要求的行以及上面兩行
-C :後跟一個數字,例如 –C2 則表示打印符合要求的行以及上下各兩行

1.過濾出帶有某個關鍵詞的行並輸出行號
grep -n ‘root‘ /etc/passwd

2.過濾不帶有某個關鍵詞的行,並輸出行號
grep -nv ‘nologin‘ /etc/passwd
3.過濾出所有包含數字的行
grep ‘[0-9]‘ /etc/inittab
4.過濾出所有不包含數字的行
grep -v ‘[0-9]‘ /etc/inittab
5.把所有以 ‘#’ 開頭的行去除
grep -v ‘^#‘ /etc/inittab
6.去除所有空行和以 ‘#’ 開頭的行
grep -v ‘^#‘ /etc/crontab |grep -v ‘^$‘
在正則表達式中, “^” 表示行的開始, “$” 表示行的結尾,那麽空行則可以用 “^$” 表示
7.過濾任意一個字符與重復字符
grep ‘r..o‘ /etc/passwd
8.指定要過濾字符出現的次數
grep ‘o{2}‘ /etc/passwd
egrep
1.篩選一個或一個以上前面的字符
egrep ‘o+‘ test.txt
2.篩選零個或一個前面的字符
egrep ‘o?‘ test.txt
3.篩選字符串1或者字符串2
egrep ‘aaa|111|ooo‘ test.txt
4.egrep中( )的應用
egrep ‘r(oo|at)o‘ test.txt
用( )表示一個整體,例如(oo)+就表示1個 ‘oo’ 或者多個 ‘oo’
egrep ‘(oo)+‘ test.txt
sed工具的使用
grep實現的只是查找功能,而它卻不能實現把查找的內容替換掉。sed工具以及下面要講的awk工具就能實現把替換的文本輸出到屏幕上的功能了,而且還有其他更豐富的功能。sed和awk都是流式編輯器,是針對文檔的行來操作的。
1.打印某行
sed -n ‘n‘p filename 單引號內的n是一個數字,表示第幾行:
sed -n ‘1,$‘p filename 把所有行都打印出來可以使用
2.打印包含某個字符串的行
sed -n ‘/root/‘p test.txt
3.-e可以實現多個行為
sed -e ‘1‘p -e ‘/111/‘p -n test.txt
4.刪除某行或者多行
sed ‘1,3‘d test.txt
‘d’ 這個字符就是刪除的動作了,不僅可以刪除指定的單行以及多行,而且還可以刪除匹配某個字符的行,另外還可以刪除從某一行一直到文檔末行。
5.替換字符或字符串
sed ‘1,2s/ot/to/g‘ test.txt
sed ‘s#ot#to#g‘ test.txt
‘s’ 就是替換的命令, ‘g’ 為本行中全局替換,如果不加 ‘g’ 只換該行中出現的第一個。除了可以使用 ‘/’ 作為分隔符外,還可以使用其他特殊字符例如 ‘#’ 或者 ‘@’ 都沒有問題。
6.調換兩個字符串的位置
sed ‘s/(rot)(.)(bash)/\3\2\1/‘ test.txt
用 () 把所想要替換的字符括起來成為一個整體,因為括號在sed中屬於特殊符號,所以需要在前面加脫意字符 ‘’, 替換時則寫成 ‘1’, ‘‘2’, ‘‘3’ 的形式。除了調換兩個字符串的位置外,還常常用到在某一行前或者後增加指定內容。
sed ‘s/^.
$/123&/‘ test.txt
7.直接修改文件的內容
sed -i ‘s/ot/to/g‘ test.txt
這個命令可以直接把文件修改.

練習:把/etc/passwd 復制到/root/test.txt,用sed打印所有行
打印test.txt的3到10行
打印test.txt 中包含 ‘root’ 的行
刪除test.txt 的15行以及以後所有行
刪除test.txt中包含 ‘bash’ 的行
替換test.txt 中 ‘root’ 為 ‘toor’
替換test.txt中 ‘/sbin/nologin’ 為 ‘/bin/login’
刪除test.txt中5到10行中所有的數字
刪除test.txt 中所有特殊字符(除了數字以及大小寫字母)
把test.txt中第一個單詞和最後一個單詞調換位置
把test.txt中出現的第一個數字和最後一個單詞替換位置
把test.txt 中第一個數字移動到行末尾
在test.txt 20行到末行最前面加 ‘aaa:’
阿銘希望你能盡量多想一想,答案只是用來作為參考的。
sed習題答案

  1. /bin/cp /etc/passwd /root/test.txt ; sed -n ‘1,$‘p test.txt
  2. sed -n ‘3,10‘p test.txt
  3. sed -n ‘/root/‘p test.txt
  4. sed ‘15,$‘d test.txt
  5. sed ‘/bash/‘d test.txt
  6. sed ‘s/root/toor/g‘ test.txt
  7. sed ‘s#sbin/nologin#bin/login#g‘ test.txt
  8. sed ‘5,10s/[0-9]//g‘ test.txt
  9. sed ‘s/[^0-9a-zA-Z]//g‘ test.txt
  10. sed ‘s/(^[a-zA-Z][a-zA-Z])([^a-zA-Z].)([^a-zA-Z])([a-zA-Z][a-zA-Z]*$)/\4\2\3\1/‘ test.txt
  11. sed ‘s#([^0-9][^0-9])([0-9][0-9])([^0-9].)([^a-zA-Z])([a-zA-Z][a-zA-Z]$)#\1\5\3\4\2#‘ test.txt
  12. sed ‘s#([^0-9][^0-9])([0-9][0-9])([^0-9].*$)#\1\3\2#‘ test.txt
  13. sed ‘20,$s/^.*$/aaa:&/‘ test.txt
    awk工具的使用
    awk比sed更加強大,它能做到sed能做到的,同樣也能做到sed不能做到的。awk工具其實是很復雜的。
    1.截取文檔中的某個段
    head -n2 /etc/passwd |awk -F ‘:‘ ‘{print $1}‘
    head -n2 test.txt |awk -F‘:‘ ‘{print $0}‘
    -F 選項的作用是指定分隔符,如果不加-F指定,則以空格或者tab為分隔符。 Print為打印的動作,用來打印出某個字段。$1為第一個字段,$2為第二個字段,依次類推,有一個特殊的那就是$0,它表示整行。
    註意awk的格式,-F後緊跟單引號,然後裏面為分隔符,print的動作要用 { } 括起來,否則會報錯。print還可以打印自定義的內容,但是自定義的內容要用雙引號括起來。
    head -n2 test.txt |awk -F‘:‘ ‘{print $1"#"$2"#"$3"#"$4}‘
    2.匹配字符或字符串
    awk ‘/oo/‘ test.txt
    awk -F ‘:‘ ‘$1 ~/oo/‘ test.txt
    可以讓某個段去匹配,這裏的’~’就是匹配的意思
    awk -F ‘:‘ ‘/root/ {print $1,$3} /test/ {print $1,$3}‘ /etc/passwd
    還可以多次匹配,如上例中匹配完root,再匹配test,它還可以只打印所匹配的段。
    3.條件操作符
    awk -F ‘:‘ ‘$3=="0"‘ /etc/passwd
    awk中是可以用邏輯符號判斷的,比如 ‘==’ 就是等於,也可以理解為 ‘精確匹配’ 另外也有 >, ‘>=, ‘<, ‘<=, ‘!= 等等,值得註意的是,在和數字比較時,若把比較的數字用雙引號引起來後,那麽awk不會認為是數字,而認為是字符,不加雙引號則認為是數字。
    awk把所有的數字當作字符來對待.
    awk -F ‘:‘ ‘$3<$4‘ /etc/passwd
    != 為不匹配,除了針對某一個段的字符進行邏輯比較外,還可以兩個段之間進行邏輯比較。
    awk -F ‘:‘ ‘$3>"5" && $3<"7"‘ /etc/passwd
    awk -F ‘:‘ ‘$3>"5" || $7=="/bin/bash"‘ /etc/passwd
    另外還可以使用 && 和 || 表示 “並且” 和 “或者” 的意思。
    4.awk的內置變量
    awk常用的變量有:
    NF :用分隔符分隔後一共有多少段
    NR :行數
    head -n3 /etc/passwd | awk -F ‘:‘ ‘{print NF}‘
    head -n3 /etc/passwd | awk -F ‘:‘ ‘{print $NF}‘
    NF 是多少段,而$NF是最後一段的值, 而NR則是行號。
    5.awk中的數學運算
    awk可以把段值更改
    head -n 3 /etc/passwd |awk -F ‘:‘ ‘$1="root"‘;
    當然還可以計算某個段的總和
    awk -F ‘:‘ ‘{(tot=tot+$3)}; END {print tot}‘ /etc/passwd

練習:
用awk 打印整個test.txt (以下操作都是用awk工具實現,針對test.txt)
查找所有包含 ‘bash’ 的行
用 ‘:’ 作為分隔符,查找第三段等於0的行
用 ‘:’ 作為分隔符,查找第一段為 ‘root’ 的行,並把該段的 ‘root’ 換成 ‘toor’ (可以連同sed一起使用)
用 ‘:’ 作為分隔符,打印最後一段
打印行數大於20的所有行
用 ‘:’ 作為分隔符,打印所有第三段小於第四段的行
用 ‘:’ 作為分隔符,打印第一段以及最後一段,並且中間用 ‘@’ 連接 (例如,第一行應該是這樣的形式 ‘root@/bin/bash‘ )
用 ‘:’ 作為分隔符,把整個文檔的第四段相加,求和
awk習題答案

  1. awk ‘{print $0}‘ test.txt
  2. awk ‘/bash/‘ test.txt
  3. awk -F‘:‘ ‘$3=="0"‘ test.txt
  4. awk -F‘:‘ ‘$1=="root"‘ test.txt |sed ‘s/root/toor/‘
  5. awk -F‘:‘ ‘{print $NF}‘ test.txt
  6. awk -F‘:‘ ‘NR>20‘ test.txt
  7. awk -F‘:‘ ‘$3<$4‘ test.txt
  8. awk -F‘:‘ ‘{print $1"@"$NF}‘ test.txt
  9. awk -F‘:‘ ‘{(sum+=$4)}; END {print sum}‘ test.txt

//擴展二//
(1)打印某行到某行之間的內容http://ask.apelearn.com/question/559
sed -n ‘/[abcfd]/,/[rty]/p‘ test 截取[abcfd]到[rty]間的內容
(2)sed轉換大小寫 http://ask.apelearn.com/question/7758
sed中,使用\u表示大寫,\l表示小寫

  1. 把每個單詞的第一個小寫字母變大寫:sed ‘s/\b[a-z]/\u&/g‘ filename
  2. 把所有小寫變大寫:sed ‘s/[a-z]/\u&/g‘ filename
  3. 大寫變小寫:sed ‘s/[A-Z]/\l&/g‘ filename
    (3)sed在某一行最後添加一個數字http://ask.apelearn.com/question/288
    (4)刪除某行到最後一行 http://ask.apelearn.com/question/213
    sed ‘/c/{p;:a;N;$!ba;d}‘ test
    定義一個標簽a,匹配c,然後N把下一行加到模式空間裏,匹配最後一行時,才退出標簽循環,然後命令d,把這個模式空間裏的內容全部清除。
    if 匹配"c"
    :a
    追加下一行
    if 不匹配"$"
    goto a
    最後退出循環,d命令刪除。
    (5)打印1到100行含某個字符串的行 http://ask.apelearn.com/question/1048
    sed指定行範圍匹配 sed -n ‘1,100{/abc/p}‘ 1.txt
    //擴展三//
    awk 用法(使用入門) http://www.cnblogs.com/emanlee/p/3327576.html
    //擴展四//
    awk 中使用外部shell變量http://ask.apelearn.com/question/199

awk 合並一個文件 http://ask.apelearn.com/question/493
awk ‘NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}‘ 1.txt 2.txt
解釋:把兩個文件中,第一列相同的行合並到同一行中。
NR表示讀取的行數, FNR表示讀取的當前行數,大家可以運行這個命令 awk ‘{print NR,FNR}‘ 1.txt 2.txt,比較NR和FNR,所以其實NR==FNR 就表示讀取1.txt的時候。 同理NR>FNR表示讀取2.txt的時候
數組a其實就相當於一個map。
把一個文件多行連接成一行 http://ask.apelearn.com/question/266
a=cat file;echo $a
awk ‘{printf("%s ",$0)}‘ file // %s 後記得要有一空格,否則出來就是完全連在一起的,中間連空格都沒有
cat file |xargs
awk中gsub函數的使用 http://ask.apelearn.com/question/200
awk ‘gsub(/www/,"abc")‘ /etc/passwd // passwd文件中把所有www替換為abc
awk -F ‘:‘ ‘gsub(/www/,"abc",$1) {print $0}‘ /etc/passwd // 替換$1中的www為abc
awk 截取指定多個域為一行 http://ask.apelearn.com/question/224
用awk指定分隔符把文本分為若幹段。如何把相同段的內容弄到一行?
以/etc/passwd為例,該文件以":"作為分隔符,分為了7段。
for i in seq 1 7
do
awk -F ‘:‘ -v a=$i ‘{printf $a " "}‘ /etc/passwd
echo
done
過濾兩個或多個關鍵詞 http://ask.apelearn.com/question/198
grep -E ‘123|abc‘ filename // 找出文件(filename)中包含123或者包含abc的行
egrep ‘123|abc‘ filename //用egrep同樣可以實現
awk ‘/123|abc/‘ filename // awk 的實現方式
用awk生成以下結構文件 http://ask.apelearn.com/question/5494
awk用print打印單引號 http://ask.apelearn.com/question/1738
比較繞,不用死記硬背,以後用的時候,稍微多試幾次就出來了。
awk ‘BEGIN{print "a‘"‘"‘s"}‘ //不用脫義,就多寫幾個單引號、雙引號
awk ‘BEGIN{print "a‘\‘‘s"}‘ //用脫義,脫義的是單引號
awk ‘BEGIN{print "a\"s"}‘ //用脫義,脫義的是雙引號
把兩個文件中相同的行合並成一行 http://ask.apelearn.com/question/945
paste filename1 filename2
如果,你想在兩個文件連接處用一個指定的字符連接,還可以用-d來指定
paste -d ‘+‘ a.txt b.txt

第9章 正則 擴展