1、文本處理_2:grep,sed,awk 2、regular_expression 3、Test 一、文本處理_2 1、grep --Linux處理正則表達式的主要程式。正則表達式是一種符號表示法,用於識別文本模式 常用選項: -w --匹配單詞的邊界 -o --輸出匹配的那部分,而不是整行 -i ...
1、文本處理_2:grep,sed,awk 2、regular_expression 3、Test 一、文本處理_2 1、grep --Linux處理正則表達式的主要程式。正則表達式是一種符號表示法,用於識別文本模式 常用選項: -w --匹配單詞的邊界 -o --輸出匹配的那部分,而不是整行 -i --忽略大小寫 -R --遞歸,用於搜索目錄下的文件 -l --輸出符合條件的文件名 -n --顯示匹配記錄的行號 -v --顯示不符合條件的結果 -c --輸出匹配的記錄的總數 -A --輸出下文(after) -B --輸出上文(before) -C --輸出上下文(context) -q --不輸出結果,常用於條件測試 -E --使用擴展的正則表達式;表達重覆的數量時,在大括弧前面不需要反斜杠,這樣正則表達式就很簡潔,易讀 # grep bin /etc/passwd --把/etc/passwd 中包含 bin 的行列出來 # grep -w bin /etc/passwd --對搜索字元有邊界限制 # grep -o bin /etc/passwd --只列出匹配到的字元串 # grep -oi nobody /etc/passwd --將匹配到的字元列出,不區分大小寫 # grep -Rl AUTOSWAP /etc/sysconfig/ --指定目錄裡面,哪個文件包含了字元串AUTOSWAP # grep -n bash /etc/passwd | awk -F: '{print $1}' --找出指定文件中 bash 所在的行的行號 # grep -n bin /etc/passwd | wc -l --找出指定文件中有多少行包含了單詞bin # grep -nv bash /etc/passwd --找出 /etc/passwd 中不包含bash 的行 # grep -c root /etc/passwd --輸出匹配行的總數 # grep -A2 mail /etc/passwd --列印出指定文件中包含 mail 的行,同時打出其下麵2行 # grep -B2 mail /etc/passwd --同上,同時打出其上面2行 # grep -C2 mail /etc/passwd --同上,同時打出其上下麵各2行 # grep -q root /etc/passwd --不輸出結果,經常用於腳本中,用來做測試 # echo $? --返回值為 0,匹配到字元;否則未匹配到指定字元 # ls /bin | grep '^.\{5\}$' --輸出 /bin 目錄下只有五個字元的命令 # ls /bin | grep -E '^.{5}$' -- 使用擴展的正則表達式 # grep -Eo '/[^:]*nologin$' /etc/passwd --正則表達式與邊界限制組合 # echo -e "1\n2" -- -e,使 echo 使用正則表達式 -------------------------------------------------------------------------------------------------------------- # cat lines | grep -v '^$' |grep -vE '^\s+$' --刪除含有空格與含有TAB的空白行 2、sed --流編輯器,常常用於腳本中 範圍指定:不明確指定的話,預設是所有的行;可以是行號;或者正則表達式 動作指定: d --刪除 s --替換 n --關閉預設的輸出 p --列印 e --連續符 -i --將修改結果寫入原文件,預設是將修改結果輸出到標準輸出 i --在前面插入 a --在後面插入 -r --使用擴展的正則表達式,使用這個參數後正則表達式的表示方法會更加方便。相當於 grep 里的 -E 2.1、刪除 # cat /etc/passwd | sed '3d' --刪除第 3 行 # cat /etc/passwd | sed '3,$d' --刪除第 3 行至最後 # cat /etc/passwd | sed '10,20d' --刪除第 10 行至第 20 行 # head /etc/passwd | cat -n |sed -e 1d -e 3d --刪除第 1 行與第 3 行 2.2、替換 # echo hello | sed 's/l/L/' --把小寫 l 替換成大寫 L,只匹配第 1 個 l # echo hello | sed 's/l/L/g' --匹配所有的 l # grep root /etc/passwd | sed 's/root/ROOT/' --為指定範圍,替換所有行第 1 個 root # grep root /etc/passwd | sed '1s/root/ROOT/' --只替換第 1 行第 1 個 root # echo "hello world" | sed 's/world//' --將字元串替換為空 替換動作的範圍: s/a/A/ --替換每行第一個a s/a/A/g --替換每行所有a s/a/A/3 --替換每行第3個a s/a/A/3g --替換每第3個至最後一個a 替換命令的分割符: 分隔符斜杠/ 可以換成任何其它的字元,需要註意的是,如果需要處理的數據中包含了分隔符,就必須對該字元進行轉義,舉例如下: # echo /etc/passwd | sed 's/\//_/g' --將字元串中的斜杠替換成下劃線 # echo /etc/passwd | sed 's#/#_#g' --作用同上,使用其他字元作為分隔符 2.3、輸出指定行 # sed -n '1,5p' /etc/passwd -- -n關閉了預設的輸出,然後只輸出第1至第5行 # sed -n '/root/p' /etc/passwd -- 輸出包含指定關鍵字的行 2.4、插入 # cat /etc/passwd | sed '5i good morning' --在第 5 行前面插入一行 # cat /etc/passwd | sed '3a good morning' --在第 3 行後面插入一行 # cat /etc/passwd | sed '4i good morning' | sed '3a good morning' --通過管道可隨意插入 # cat /etc/passwd | sed -e '4i good morning' -e '3a good morning' --也可使用連續符 2.5、正則 # sed '/^.\{5\}x/d' /etc/passwd | cat -n --刪除指定文件第 6 個字元為 x 的每行 # sed -r '/^.{5}x/d' /etc/passwd --同上 # echo 123456789ABCDEF | sed -r 's/^(.{2})...(.*)$/\1\2/' --刪除第 3 至第 5 的字元 # echo 123456789ABCDEF | sed -r 's/^(.{2}).(.*)$/\1\2/' --刪除第 3 個字元 # echo 123456789ABCDEF | sed -r 's/^(.{2}).{10}(.*)$/\1\2/' --刪除從3個字元開始的10個字元 # echo abc | sed -r 's/[a-z]/\u&/g' --小寫轉為大寫 # echo ABC | sed -r 's/[A-Z]/\L&/g' --大寫轉為小寫 # echo ABC | sed -r 's/./\l&/g' --同上 # sed -r -e '/^$/d' -e '/^\s+$/d' /path/file --刪除空白行 以及 含有空格的空白行 # sed -r '/^(\s+)?$/d' /path/file --同上 # sed -r '/xxxxxx/d' --刪除包含指定關鍵字的行 3、awk --文本分析工具 -F --欄位分割符,可以是一個字元,也可以是多個字元。預設的分割符為單個或連續的空格 $NF --最後一個列,NF 是number of fields:有欄位的總數 $0 --整條記錄 # awk -F '[ :]' '{print $3,$4}' /etc/passwd --以 【空格符】 or 【:】 為分隔符 # head /etc/passwd | awk -F: '{print $1,$2}' | column -t # echo 'hello world, good morning' | awk -F, '{print $1}' # head -n5 /etc/passwd | awk -F: '{print $NF}' --拿文件各行的最後一列,不管文件幾行內容列數是否相同 3.1、FS Field separator:欄位分割符。欄位分割符除了可以通過命令行選項 -F 來指定外,還可以在awk 裡面指定 BEGIN:後面的代碼會在處理第一行數據之前先執行,可以在這裡做一些前期的設定,比如設定分割符FS # head -n5 /etc/passwd | awk 'BEGIN{FS=":"} {print $1}' # head -n5 /etc/passwd | awk -F: '{print $1}' 3.2、NR number of records:到當前行為止,總共處理的行數 # head /etc/passwd | awk '{printf("%05d:: george--%s\n",NR,$0)}' --NR統計總共處理的行數,通過%05d的格式輸出 # awk 'END{print NR}' /etc/passwd --直接用來計算總行數 # awk -F: '{if (NR==1){print $1}}' /etc/passwd --只處理第一行 3.3、FNR # ls -l /etc/ | sed 1d | awk 'BEGIN{print "start to process "} {total = total + $5} END{print NR " line Finished,resrlt: " total " kb"}' --初略計算 /etc 下的文件大小 3.4、結合正則 # ls -l | sed 1d | awk '{print $5,$0}' | sort -k1,1h | sed -r 's/^[^ ]+\s*//' --將當前目錄的文件按文件大小排列。[^ ]+表示多個非空,\s 表示空格符 3.5、實例 # awk '{print $1}' access.log |sort|uniq -c|sort -nr|head -10 --分析access.log獲得訪問前10位的ip地址 二、regular_expression 1、正則表達式 正則表達式是對字元串操作的一種邏輯公式;就是用事先定義好的一些特定字元、及這些特定字元的組合,組成一個“規則字元串”, 這個“規則字元串”用來表達對字元串的一種過濾邏輯;規定一些特殊語法表示字元類、數量限定符和位置關係,然後用這些特殊語法和普 通字元一起表示一個模式,這就是正則表達式(Regular Expression) 2、特點 2.1、靈活性、邏輯性和功能性非常的強; 2.2、可以迅速地用極簡單的方式達到字元串的複雜控制。 2.3、對於剛接觸的人來說,比較晦澀難懂 3、單字元表示法 . --匹配任意字元 \d --匹配一個數字字元。等價於 [0-9] \D --匹配一個非數字字元。等價於 [^0-9] \f --匹配一個換頁符。等價於 \x0c 和 \cL \n --匹配一個換行符。等價於 \x0a 和 \cJ \r --匹配一個回車符。等價於 \x0d 和 \cM \s --匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \f\n\r\t\v] \S --匹配任何非空白字元。等價於 [^ \f\n\r\t\v] \t --匹配一個製表符。等價於 \x09 和 \cI \v --匹配一個垂直製表符。等價於 \x0b 和 \cK \w --匹配包括下劃線的任何單詞字元。等價於'[A-Za-z0-9_]' 4、邊界表示法 ^ --字元串的開頭 $ --字元串的結尾 \b --單詞邊界 \B --非單詞邊界 \< --單詞左邊界 \> --單詞右邊界 5、分組表示法 (abc) --一組連續的字元abc (aa|bb) --一組連續的字元ab 或者 bb 6、字元集合 [xyz] --字元集合。匹配所包含的任意一個字元 [^xyz] --負值字元集合。匹配未包含的任意字元 [a-z] --字元範圍。匹配指定範圍內的任意字元 [^a-z] --負值字元範圍。匹配任何不在指定範圍內的任意字元 7、數量表示法 --用來表示前面的一個字元,或者一組字元重覆的次數 * --任意次, c >= 0 + --至少1次, c >= 1 ? --0次或者1次, c == 0 || c == 1 {m} --m 次, c == m {m,} --至少m 次, c >= m {m,n} --m次 至 n次, c >= m && c <= n 註意:預設情況下,數量表示符只作用於前面一個字元,若需要作用於前面多個字元,可以使用(...)把前面需要匹配的多個字元括起來 8、特殊字元表示法 ^ $ . * + ? | \ { } [ ] ( ) 都有特殊意義的,如果需要表示這些符號,則可以用反斜杠對它們進行轉義 9、引用表示法 從左邊開始數左邊小括弧,數字從1開始,被第一對括弧匹配的字元可以用\1 來引用,第二對可以用\2 來引用,以此類推 # echo abcabcabcaabb | grep -E '(a(bc)){2}\1' --color # echo abcabcabcaabb | grep -E '(a(bc)){2}a\2' --color # echo "hello world, hello world, hello beautiful world" | grep -E --color '((hello) (world)), \1, \2 .* \3' 10、其他表示方法 # date # date | grep --color -oE '([0-1][0-9]|2[0-3])(:[0-5][0-9]){2}' --時間表示 # echo 2014-07-07 12:30:30 | grep --color -E '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])' --日期表示 # ifconfig | grep --color -E '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' --IP地址表示 # ifconfig | grep --color -E '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' --MAC表示 三、測試 1、獲取eth0的IP地址 # ifconfig eth0 | grep 'inet addr' | awk -F: '{print $2}' | awk '{print $1}' # ifconfig eth0 | grep 'inet addr' | sed 's/.*addr://;s/ .*//' 2、查看root 用戶的登錄shell # grep ^root /etc/passwd | awk -F: '{print $NF}' 3、查看/etc/passwd中有多少種登錄shell # awk -F: '{print $NF}' /etc/passwd | sort -u | wc -l # sed 's/.*://' /etc/passwd | sort -u | wc -l 4、計算多個文件的總行數/總大小 # cat * | wc -l # cat * | wc -c 5、計算字元串的長度 # echo 123 | wc -c -- 多出的一個是換行符 # echo -n 123 | wc -c -- 禁止輸出換行符 6、在文件第一行之前和最後一行之後輸出一些字元 # cat /etc/hosts | sed -e '1i ***********************' -e '$a ***********************' # cat /etc/hosts | awk 'BEGIN{print "xxxxxxx"} {print $0} END{print "xxxxxxx"}' 7、輸出系統開放的所有埠號 # netstat -tulpn | awk '{print $4}' | awk -F: '{print $NF}' | grep [0-9] | sort -nu 8、計算線上用戶 # who | wc -l 9、歷史開關機記錄 # last -x | grep -E 'reboot|shutdown' 10、查根文件系統的可用空間 # df -h | grep " /$" | awk '{print $(NF-2)}' 11、查看sshd 登錄記錄,輸出時間,用戶名,客戶端IP # grep -E 'sshd.*Accepted pub' /var/log/secure-20170528 | awk '{print $1,$2,$3,$9,$11}' 12、系統至開機總運行時間 # uptime | awk -F, '{print $1,$2}' | sed 's/.*up //' | tr -s " " 13、將十進位 IP 地址轉換為二進位的 IP 地址 # echo 192.168.3.33 | sed -e 's/\./;/g' -e 's/^/obase=2;ibase=10;/' | bc | xargs printf "%08d." | sed 's/.$/\n/' # echo "obase=2;ibase=10;192;168;3;33" | bc | xargs printf "%08d." | sed 's/.$/\n/' 14、刪除行首兩個字元 # sed 's/^..//' # tail -c +3 15、刪除行尾兩個字元 # sed 's/..$//' # head -c -2 16、把字元串中的大寫A替換成小寫A # sed 's/A/a/g' # tr A a 17、判斷字元串是否以 A 開頭 if grep -Eq '^A'; then if [ "$(echo $str | sed 's/^A//')" != "$str" ];then if [ "${str#A}" != "$str" ]; then 18、判斷字元串是否以 A 結尾 if grep -Eq 'A$'; then if [ "$(echo $str | sed 's/A$//')" != "$str" ];then if [ "${str%A}" != "$str" ]; then 19、截取字元串前面兩個字元 # head -c 2 # grep -oE '^..' # cut -c 1-2 # sed -r 's/^(..).*$/\1/' 20、截取字元串後面兩個字元 # grep -oE '..$' # tail -c 2 # sed -r 's/^.*(..)$/\1/' 21、截取字元串中第3至第5個字元 # cut -c 3-5 # sed -r 's/^..(...).*$/\1/' # head -c5 | tail -c3 22、截取字元串中第1,第3,第8至第10,第12至末尾的字元 # cut -c1,3,8-10,12- # awk 'BEGIN{FS=""} { for(i=1;i<=NF;i++) {if (i==1 || i== 3 || (i>=8 && i<=10) || i>=12) print $i } }' | tr -d $'\n' 23、去除數據中的重覆行 # sort -u # sort | uniq 24、計算數據中相同的行出現的次數 # sort | uniq -c 25、進行大文件的切割,每個小文件為100M # head -c 2G /dev/urandom > bigfile # split -b104857600 bigfile bigfile_ 26、查找文件中單詞 bin 出現的次數 # grep -wo bin /etc/passwd | wc -l 27、刪除文件空白行 # grep -vE '^$' /etc/ssh/sshd_config --不能刪除有空格符的空白行 # grep -vE '^\s*$' /etc/ssh/sshd_config --可以刪除有空格符的空白行 28、把/etc/passwd 中所有的/bin/bash 登錄shell 替換成 /sbin/nologin # sed -E 's#/bin/bash#/sbin/nologin#g' /etc/passwd 29、統計文件 /etc/passwd 各個單詞出現的頻率 # grep -oE '\w+' /etc/passwd | sort | uniq -c | sed -r 's/^ +//' # cat /etc/passwd | sed 's/[:/ ]/\n/g' | sed '/^$/d' | sort | uniq -c | sed -E 's/^\s+//' | sort -k1,1n # cat /etc/passwd | grep -Eo '\w+' | sort | uniq -c | sed -E 's/^\s+//' | sort -k1,1n # cat /etc/passwd | sed 's/[:/ ]/\n/g' | sed '/^$/d' | sort | uniq -c | sort -t" " -k6,6n 30、字元串檢測 # echo abcd | grep -oE '^[a-z]+$' --測試字元串是否純小寫 # echo 12344323 |grep -oE '^[0-9]+$' --測試字元串是否純數字 # echo iiiIIII | grep -oE '^[a-zA-Z]+$' --測試字元串是否純字母 # echo 3425 |grep -E '^(0|[1-9][0-9]*)$' --測試字元串是否非負整數 # echo 3 |grep -E '^[1-9][0-9]*$' --測試字元串是否正整數 # echo -23 |grep -E '^-[1-9][0-9]*$' --測試字元串是否負整數 # echo 0 | grep -E '^(-[1-9][0-9]*)|(0|[1-9][0-9]*)$' --測試字元串是否整數 # echo -0.30000 | grep -E '^(-[1-9][0-9]*|[+-]?0|[1-9][0-9]*)\.[0-9]+$' --測試字元串是否小數 # echo _9kdj_324kdsd_dk | grep '^[a-zA-Z_][a-zA-Z0-9_]*$' --測試字元串是否只包含字母、數字、下劃線,而且不以數字開頭