Linux & unix shell 筆記 (正則表達式,grep, awk, sed )
第七章 正則表達式
* 表任意字符,但要使用時前面要加一個字母,表示該字母可以為任意數,任意多個;它還有任意結果任意多次的意思,注意并不單指前面的字符任意多次 如:grep a* test.txt 或 grep a.* test
查找任意字母開頭的行 grep [a-zA-Z] test.txt grep ^ [a-zA-Z] test.txt 非字母開頭的 [^a-zA-Z] 非數字開頭的[^0-9] 空白行 grep ^$ test.txt 顯示非空白行 grep [^$] test.txt grep –v ^$ test.txt 中括號內加^意指否定,不匹配括號內的內容
模式A為單個字符時可用,為一組合字符時如:abc;查找多次時查找會出現問題
grep 的使用
-o only match 只打印匹配的文本 -P perl regexp 使用perl 表達式
grep –E 與 –e 選項的區別,在書寫上有差別,意思是一致的 grep –E ‘219|216’ data.f grep –e ‘219 –e 216 data.f egrep ‘219|216’ data.f
9.AWK 介紹
awk 'BEGIN {print \"Name\\n----------\grade.txt
awk ‘模式{動作}模式{動作}模式{動作}’
==============================
awk ‘{if($4~/Brown/) print $0}’ grade.txt
/Brown/ 為下則表達式在awk中的使用方法
awk ‘$0~/Brown/’ grade.txt 匹配模式后,默認會打印輸出符合的所有記錄﹔awk命令可以只有模式,或只有動作,很靈活
awk ‘$3==”48” {print $0}’ grade.txt
awk ‘模式 {動作}’ 文件(輸入) awk 命令的標准使用方法 精確匹配用==,模糊的,使用與正則表達式匹配用~,/內容/
!~,!=,~,== 模糊與精確匹配操作符
復合模式,使用邏輯語句
兩個條件間單獨考慮,“||"與“|"符合比較起來“||"可以使兩個條件分別精確或模糊匹配,“|"確只能用在同條件下。
awk 內置變量的使用,比較難記
NF 的實際應用實例為輸出文件名
注意:輸出NF 與 $NF 是不同的意思﹔NF指域的數量,$NF則為每條記錄的
最后一個域值
關系操作,條件語句必須用圓括號括起來﹔關系操作中可用實際數值 把兩條語句放一起執行用花括號括起來,中間用分號分開(兩條命令)
逗號用于分開同不同的變量
注意:1> awk ‘{if($1==”J.Troll”) ($1=”J.L.Troll”); print $1}’ grade.txt 2> awk ‘{if($1==”J.Troll”) {$1=”J.L.Troll” print $1}}’ grade.txt 兩個命令花括號的位置,及分號。兩個命令表達的含義是不同的 1> 中if($1==”J.Troll”) ($1=”J.L.Troll”);為一個模式,print $1為動作 2> 中if($1==”J.Troll”)為模式,{$1=”J.L.Troll” print $1}}為動作
“+="用于統計列值
sub 替代
gsub(r,s,t) 指定在t中查找,用s替代r
awk ‘gsub(/4832/,4899,$3) {print $0}’ grade.txt
gsub 查找所有的全部替換, sub只查找替換匹配的第一個
awk '$1==\"J.Troll\" sub(/26/,\"29\awk '$1==\"J.Troll\" sub(/26/,\"29\"); {print $0}' grade.txt
sub (/op/,”OP”,STR) ,sub(/op/,”OP”)模式 是一樣的輸出結果
substr(r,s,t) 與substr(r,s) 是一個意思,截取從某個字符開始的一串字符,t表示最后一個是多少,沒有時為全部
printf 函數專用于格式化輸出,使整個輸出更美觀。
awk 'BEGIN {print \"Name \\S.number\%-15s %s 表示輸出字符串,- 左對齊 15個字符
這里輸出的是兩個域,第一個域被限制只輸出15個字符,$3按第二個格式輸出,如果省略該格式意味著$3不輸出。
[root@test ~]# awk '{printf \"%15s \
M.Tansley J.Lulu P.Bunny J.Troll L.Tansley
awk 腳本文件
腳本應該如下
[root@test ~]# cat passwd.awk
#!/bin/awk -f
#to call:passwd.awk /etc/passwd #print out the first and fifth fields BEGIN { FS=\":\" }
{print $1,\"\\
注意下各個括號的位置,否則會產生錯誤
#!/bin/awk –f含義相當于告訴系統如下調用命令 awk –f passwd.awk /etc/passwd
For 循環語法
For (element in array ) print array[element]
belt[\"yellow\"]表示 belt[yellow]
在awk中数组叫做关联数组(associative arrays),因为下标记可以是数也 可以是串。awk中的数组不必提前声明,也不必声明大小。数组元素用0或 空串来初始化,这根据上下文而定。 1) 关联数组的下标 .. 把变量用作数组索引。 举例:
$ nawk '{name[x++]=$2};END{for(i=0;i 0 Jones 1 Adams 2 Chang 3 Black 解释:在数组name里的下标是一个用户自定义变量x。++显示了一个 数值型的上下文。 .. 特殊for循环 在for循环无效的情况下,即当串被用作下标或者下标不是连续的数 时,用特殊for循环来读取一个关联数组。特殊for循环把下标当作 一个键来找到它的相关的值。 格式: {for(item in arrayname){ print arrayname[item]}} 举例: $ nawk '/^Tom/{name[NR]=$1};\\ >; END{for(i=1;i<=NR;i++) print name}' db Tom Tom Tom Tommy $ nawk '/^Tom/{name[NR]=$1};\\ >; END{for(i in name){print name}}' db Tom Tom Tommy Tom 解释:这两个例子用NR(行号)来做下标,因此匹配Tom的模式的行 不连续,数组下标不连续。如果用传统for来循环打印会在数组没有 值的地方打印空值。通过使用特殊for循环,只打印数组中有值的内 容 For 循環有兩種方式,變量(數字)作下標﹔串用作下標。Split函數連用,非常實用。。。。 兩種下標方式,讀取就有所不同了。。 數組的使用是難點,和比較實用的地方。下面有個實例。 一个a.file文件 11 1.txt 20 1.txt 5 d.docx 5 y.doc 7 d.docx 要求的输出格式是这样的: txt:31 docx:12 doc:5 awk '{split($2,a,\".\");b[a[2]]+=$1}END{for(i in b)print i\":\"b[i]}' a.file awk -F '[ .]+' '{a[$NF]+=$1}END{for (j in a) print j\":\"a[j]}' file [root@test bin]# awk '{split($2,a);b[a[1]]+=$1}END{for (i in b) print i\":\"b[i]}' a.file d.docx:12 y.doc:5 1.txt:31 Split 函數的使用。要學會。 10.Sed 命令介紹 ============================================================= 打印sed –n ‘[start [,end] p’ inputFile 打印第start行,或從start,end行 sed –n ‘/string/’p inputFile 打印查找,匹配的行; p 字符要跟在正則表達式后面 可以這樣理解這兩個選項 -n next 跳過其它的行 –p print打印 用行號與模式來精確匹配 x,/pattern/ 注意p出現的位置在 正則表達式與行號匹配 時有所不同 sed -n '/any.$/'p quote.txt sed查找的是整行,這樣寫匹配的是行尾 sed -n '/.*ing /'p quote.txt 這樣寫才是匹配其中某個單詞,字母 附加操作:[address]a\\ 具體為插入一個新行,執行后面的附加動作 sed '4 i\\Utter confusion followed.' quote.txt 會在第四行前面位置插入該行,成為新的第 四行 sed '3 c\\The office dibble band play well.' quote.txt sed -p 's/The/Wow!/w sed.out' quote.txt sed -n 's/played/from Hockering &/p' sed/quote.txt sed -n 's/played/& from Hockering /p' sed/quote.txt &號表示發現的部分,可以放置在前,后面位置 sed '/company./r sedex.txt' quote.txt sed '/music/r sedex.txt' quote.txt 兩個命令輸出結果是一樣的,模式匹配后自動將讀取的 文件輸出到下一行。 sed '/.a.*/q' quote.txt 查詢首次匹配后就會退出,不再繼續處理。 sed -n '1,$l' func.txt 顯示控制字符,但與cat –v func.txt命令中顯示的控制字符不同。不明白。。。 cat -v dos.txt|sed 's/##*//g'|sed 's/^0*//g'|sed 's/\\^M//' ^M 標志是windows系統的分行標識符,在linux下可以這樣產生 Ctrl+V鍵同時按下,先松開V鍵,再緊接著按下M鍵,再兩個按鍵同時松下。就會產生。可以按光標移動看每次跑動的格數為一格說明是正確的,或者在vi下保存,使用cat 正常查看不到時說明正確。 解決windows系統的^M字符問題可以用dos2unix命令轉換文本 sed 's/^[0-9]*//g' UNH.txt 修改數據,sed 命令進行的是向下方向移動的橫向對比操作,針對整個文本文件 awk 命令進行的是橫向移動的向下分域對比操作,針對每一條記錄(橫排) 1.從shell命令行中向sed傳值要用雙引號 2.從sed輸出中設置shell變量要考慮命令執行順序,這里要用反引號,讓命令執行后賦值 3.sed 不區分大小寫,從上例可以看出 實例 Sed 表達式里的所有特殊符號都要轉義,,單引號在這里并不能屏蔽其特殊含義。 下面有個網頁實例, aaahref=\"/search_db.asp?keyword=%E8%B0%83%E8%AF%95\" target=\"_blank\">正在搜索调试 bbbtarget=\"_blank\">正在下载C#.NET开发的MIS打印程序.rar 要取出aaa、bbb等等! 1.grep -oP '(?<=color=\"#0000b0\">)[^<]*' file 2.sed 's/.*#0000b0\">\\(.*\\)/\\1/' file|awk -F '<' '{print $1} 3.sed 's/.*#0000b0\">\\(.*\\)/\\1/' file | sed 's/<\\/font.*//' 4.sed 's/.*#0000b0\">\\([^<]*\\).*/\\1/' urfile 5.sed 's!!!' urfile s/...\\(..\\).../\\1/ 這個格式,語法 \\1 代表什么? Sort ,uniq,join,paste, ,cut ,.split 的用法 sort 默認是對行進行分類,排列﹔可以使用按域進行分類,-t 指定域分類符,不指定域時默認會返回基于第一域0的結果 使用sort –c video.txt 測試文件是否已分類,沒有分類會返回錯誤,否則會回到提示符 sort +n 選項無法在centos下單獨使用,可以這樣 sort +n –n 詳見后 新命令使用-k選項可以替用,sort -k start,end files (关键字开始列/域,关键字结束列/域)﹔k選項可以只加起始列,且這個列/域是從1開始算起,而不是從0。上面的命令可改為 sort –t: -k2 video.txt -n 選項完全可以用-k選項替用 -n 按數值域分類,不加時,數值會先只比較數值的第一個數,相同時再比較第二個,這樣產生的結果不准備,因此n在數值域分類時不可以省的。 sort –t: -k4n video.txt sort –t: -k3n video.txt sort -t: +0 -2 +3 video.txt 這條命令可以執行,真是怪。。測試發現,在出現加號時同時要出線減號,命令就不會報錯了。。如:sort -t: +3 -2 video.txt sort –t: +1.2 -2 video.txt sort應用 使用-m選項,合并兩個文件輸出 sort –m sorted_file1 sorted_file2 ============================================== uniq 默認為去掉連接重復的行,-u不顯示重復的行,.-u選項在uniq里指去掉連續出現的行,在不連續出現時不會去掉,uniq使用其它選項時,也均是計算不連續出現的情況﹔當直接不加任何選項是,默認為將重復的行壓縮成一行。 注意:sort –u myfile.txt 與 uniq –u myfile.txt 結果是不一樣的,sort –u 是真正的唯一。。 uniq –f2 parts.txt 測試域的唯一性,或者針對某個域進行唯一性比對 ============================================== Join –o 1.1 2.2 name.txt town.txt Join –j 1.1 –j 2.2 name.txt town.txt 第1個文件的第1 域與第2個文件的第2域連接 Join –a1 [–a2] name.txt town.txt 顯示第1 個文件 和第2個文件的不匹配選項 sort –m 的連接,只是把一個文件追加到另一個文件后,相似記錄放緊接著放 Cut 命令 –d 指定域分隔符 –f 指定剪切哪個域 paste 命令可以在兩個文件沒有相關性的條件下合并,默認是按行合并,-s選項是將每個文件合并成行(按列合并).-d指定域分隔符join命令的合并時必需要有 相關聯的地方才行。 split -3 video.txt video3.txt 會在生成的文件名后自動加aa-zz的后綴 tr 作用 大小寫轉換 去除控制字符 刪除空行 標准格式如tr “[a-z]” [A-Z]” inputfile 因篇幅问题不能全部显示,请点此查看更多更全内容