1. 程式人生 > >linux命令小記(grep、awk、sed)

linux命令小記(grep、awk、sed)

grep

  • grep 標準
  • egrep 擴充套件grep,支援基本和正則,執行效果與grep -E相似
  • fgrep 快速grep,允許查詢字串而不是一個模式

常用引數

-c 只輸出匹配的行的總數(count)
-C 加引數num表示,顯示匹配的行,及其前後num行
-d 當引數不是普通檔案而是目錄時
-f 把要匹配的模式寫進一個檔案中,然後傳給grep
-h 查詢多個檔案時,不顯示檔名
-l 查詢多個檔案時,只輸出包含匹配模式的檔案的檔名
-n 顯示匹配的行及行號
-s 不顯示不存在或無匹配檔案等錯誤資訊(silence)
-v 只顯示不包含匹配模式的行

例項

grep -c “fa>” file1

表示匹配fa,23fa等,不匹配falv這種形式,輸出行數
grep -C 2 “fa>” file1 表示輸出匹配行,並輸出其前後兩行
grep -E “[1-9]+” 或 egrep “[1-9]+” ,表示匹配一個數字或多個數字
grep -f file1 file2 表示將file1作為pattern,用file1每一行為一個模式去匹配file2中每一行,當檔案大時,消耗很大
grep -v ‘^$’ file 去除檔案file中的空行
grep -rl “eth0” /etc 檢視/etc目錄中於”eth0”有關的檔案的檔名

awk

基本功能是在檔案或字串中基於指定規則來分解抽取資訊,也可以基於指定的規則來輸出資料。完整的awk指令碼通常用來格式化文字檔案中的資訊。

三種方式呼叫

  1. awk [opion] ‘awk_script’ inputfile1 [inputfile2 …]
    -F fs 使用fs作為輸入記錄的欄位分隔符,若省略,則使用環境變數IFS的值
    -f filename 從filename中讀取awk_script
    -v var=value 為awk_script設定變數
  2. 將awk_script放入指令碼並以#!/bin/awk -f作為首行,給指令碼執行許可權,然後在shell下通過鍵入指令碼名呼叫
  3. 將所有的awk_script插入一個單獨指令碼檔案,然後呼叫awk -f 指令碼檔案

awk變數

1)awk內部變數,用於儲存awk執行時的各種引數

自動內部變數,不應被賦值和改變的

 NF   當前輸入欄位的欄位數
 NR   對當前輸入檔案而已,已經被awk讀取過的記錄(行)數
 FNR   已經被aw讀取過的記錄總數。 當僅有一個輸入檔案時,FNR和NR一致
 FILENAME   當前輸入檔案的檔名
 ARGC   命令列引數的個數(不包括awk_script, 實際就是輸入檔案數目加1)
 ARGIND   當前被處理的檔案在陣列ARGV內的索引(實際上ARGV[1]就是第一個輸入檔案)
 舉例: awk '{print NR, NF, $0} END {print FILENAME}' input_file

欄位變數(01 23…)當awk把當前輸入記錄分段時,會對這些欄位變數賦值。和內部變數類似,在awk執行過程中欄位變數的值是動態變化的。不同的是,修改這些欄位變數的值是有意義的,被修改的欄位值,可以在輸出中體現

其他內部變數:可以修改

  FS   輸入記錄的欄位分隔符(預設空格和製表符)
  OFS   輸出記錄的欄位分隔符(預設是空格)
  OFMT   數字的輸出格式(預設是%.6g)
  RS   輸入記錄見的分隔符(預設是NEWLINE)
  ORS   輸出記錄見的分隔符(預設是NEWLINE)
  ARGV   命令列引數陣列
  ENVIRON   儲存系統當前環境變數值的陣列,它的每個成員的索引就是一個環境變數名,而對應的值就是相應環境變數值。 賦值後,新值只在awk_script中有效
2)自定義變數
 a)varname=value(不需要提前宣告)
 b)在表示式中,不帶雙引號的字串都被視為變數,如果之前沒被賦值,預設值0或空字串
3)向命令列awk傳遞變數值
 awk 'awk_script' awkvar1=value1 awkvar2=value2 .... inputfile
 awkvar可以是awk內建變數或自定義變數
 awkvar的值將在awk開始對輸入檔案的第一條記錄應用awk_script前傳入。如果在awk_script中已經對某個變數賦值,那麼在命令列上傳入到該變數的值就會無效。(被覆蓋)
 在awk指令碼中,不能直接使用shell變數。

內建函式

     int(x)   qiux的整數部分(int(-3.9)值是-3int(3.8)值是3sqrt(x)   求出x正的平方根值
     exp(x)   求x的次方
     log(x)   求x的自然對數
     sin(x)   求x的sine值
     cos(x)   求x的cosine值
     atan2(y, x)   求y/x的arctangent值
     rand()   得到一個分佈在0-1的蘇技術,每次執行gawk,rand從相同的seed生成值
     srand(x)   設定產生隨機數的seed為x,如果在第二次執行awk時,設定相同seed值,會得到相同隨機數。 省略引數x,如srand(),則當前日期會被當做seed,得到真正的隨機數。
     index(in, find)  返回in中,find第一次出現的位置,索引從1開始,如果in中沒有find,返回0
     length(s)   求出s的字元個數
     match(s, r)   返回模式字串r在s第一次出現的位置,若s不包含r,返回0
     sprintf(fmt, exp1, ...)   返回經過fmt格式化後的exp
     sub(p, r, t)   在字串t中尋找符合模式字串p的最靠前最長的位置,並以字串r代替最前的p
     gsub(p, r, t)   在字串t中以r代替所有的p
     substr(str, st, len)   傳回str的zi字串,其長度為len,從strd位置st開始, len預設從st到結束
     split(s, a, fs)   在分隔符fs為分隔符將字串s分隔成一個awk陣列a,並返回a的下表數
     tolower(str)   將字串str的大寫字母改為小寫字母
     toupper(str)   將字串str的小寫字母改為大寫字母

例項

awk '{if(index($1,".")<=10){print $0}}' file1 > file2
#output:00003.mb.vmod.cn
#對於file1中的每一行,對第一個引數$1找第一個‘.'的位置,如果小於等於10,則輸出這一行

hour1=`date -d "-1 hour" +%H`
hour2=`date -d "-2 hour" +%H`
grep -E "prefix-($hour1|$hour2)" file1 | awk '{print $NF}'
#輸出匹配的最後一項

awk '{if(length($1)>5){print $1}}' file1
#輸出file1中第一列長度大於5的行的第一列
#如某行 hello! word! 則輸出hello!

awk -F '\t' '!a[$1]++' file1
#去重,因為awk是一行一行的處理,比用sort -u要方便快速消耗小
#-F指定了分隔符

sed

sed操作的是一個輸入檔案在記憶體的一個副本,對副本內容進行編輯活動,如果沒有重定向到一個檔案,會將檔案修改的結果輸出到螢幕。和awk一樣,不會修改輸入檔案的內容。

sed從輸入資料中讀取一行,將之拷貝到一個編輯緩衝區,然後讀命令列或指令碼的第一條命令,並使用這些命令中指定的定位模式來確定是否編輯和如何編輯。 重複這個過程直至結束。

sed [選項] ‘sed_cmd’ input_file

選項:
-n 預設在講下一行讀入緩衝區前,自動輸出緩衝區內容。
-e 如果在命令列呼叫多條sed_cmd,必須在每天sed_cmd前加’-e’選項

sed_cmd格式: ‘[address] sed_edit_cmd’
address sed的行定位模式,用於只是被編輯的行,省略時編輯所有行
sed_edit_cmd 對被編輯行將要進行的編輯操作

執行sed:
除了直接輸入命令列;也可以將sed寫入指令碼,用sed -f filename 執行;或者直接寫sed指令碼以“#!/bin/sed -f”開頭,通過指令碼檔名執行

address定位:
x 行號
x,y 從第x行到第y行
/pattern/ 查詢包含模式的行
x,y 查詢不包含x和y的行

sed_edit_cmd
p 列印匹配行的行號
= 顯示匹配行的行號
a\ 在指定行後附加新文字
i\ 在指定行前插入新文字
d 刪除被指定的行
c\ 用新文字替換被定位文字行
s 用模式替換被定位行中的模式
r 從另外一個檔案中讀入文字附加到指定的行後,並顯示讀入的文字資訊
w 寫文字到一個檔案

例項

sed 's/\.$//g'  刪除已據點結尾的行
sed '/abcd/d'   刪除包含abcd的行
sed '   */ /g'  刪除多個空格,用一個空格代替
sed '/^$/d'     刪除空行