1、總結sed和awk的詳細用法;
sed Sed本質上是一個編輯器,但是它是非交互式的;同時它又是面向字符流的,輸入的字符流經過sed的處理后輸出。 Sed本身是一個管道命令,可以分析standard input的,主要是用來分析關鍵字的使用、統計等,此外還可以將數據進行替換、刪除、 選取特定行等功能 格式:sed [option] ... 'script' inputfile... script: '地址命令' 常用選項: -n:不輸出模式中的內容至屏幕,只列出經過sed處理過的那一行。 -e:多點編輯,直接在命令行模式上進行sed的動作編輯。 -f:將sed的動作寫在一個文件內,-f filename則可以執行filename內的sed 動作。 -r:支持使用擴展正則表達式; -i:直接修改讀取的文件內容,而不是由屏幕輸出。 地址定界: (1)不給地址:對全文進行處理; (2)單地址: #:指定的行; /pattern/:被此處模式所能夠匹配到的每一行; (3)地址范圍: #,# #,+# /part1/,/part2/ 編輯命令: d:刪除 p:顯示模式空間中的內容 a \text:在行后面追加文本;支持使用\n實現多行追加; i \text:在行前面插入文本;支持使用\n實現多行插入; c \text:替換行為單行或多行文本; w /path/to/somefile:保存模式空間匹配到的行至指定文件中; r /path/from/some:讀取指定文件的文本流至模式空間中匹配到的行的行后; =:為模式空間中的行打印行號; !:取反條件; s///:支持使用其它分隔符,s@@@,S###; 替換標記: g:行內全局替換; p:顯示替換成功的行; w /PATH/TO/SOMEFILE:將替換成功的結果保存至指定文件中; 常用案例 以行為單位的新增加刪除功能 1、nl /etc/passwd | sed '2,5d' 說明: sed的動作為'2,5d',d就是刪除,命令運行的結果就是把2~5行給刪除。 sed后面接的動作,必須以''兩個單引號括住。 如果只想刪除第二行,命令就是nl /etc/passwd | sed '2d' 如果想刪除第2行到最后一行,可以這么寫:nl /etc/passwd | sed '2,$d' 2、nl /etc/passwd | sed '2a play game' 說明: 命令執行效果就是在第二行后面(也就是第三行)加上“play game”字樣 如果想在第二行前面加上字符器,可以這樣: nl /etc/passwd | sed '2i play game' 注:2a中的a追加的意思,指第二行后面,而2i中的i是插入的意思,指第二行的前面。 3、nl /etc/passwd | sed '2a play game or ...\nplay football' 說明: 命令執行結果是在第二行后面加入2行字。 在每一行的后面必須以\n來進行新行的增加 以行為單位的替換與顯示功能 1、nl /etc/passwd | sed '2,5c No 2~5 number' 說明: 命令的執行效果是將第2~5行的內容替換成"No 2~5 number" 2、nl /etc/passwd | sed -n '5,7p' 說明: 命令的執行效果是僅打印出文件中的第5~7行 命令中的-n代表是的安靜模式! 3、sed 's/要被替換的內容/新內容/g' 說明: 命令執行的效果就是替換掉指定內容 4、記錄一次獲取IP地址的過程 第一步:先查詢IP /sbin/ifconfig eth0 注:目的是要獲取IP數據,那么先利用關鍵字找出那一行 第二步:利用關鍵字配置grep選取出關鍵的一行數據 /sbin/ifconfig eth0 | grep 'inet addr' 注:因為只需要IP數據,所以接下來就是把不需要的內容刪除,需要一個正則表達式來幫助實現: ^.*inet addr 第三步:將IP前面的部分予以刪除 /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' 注:上面的命令就是把IP前面的數據刪除掉了,接下來就是把IP后面的數據也刪除,此時的正則表達式是: Bcast.*$ 第四步:將IP后面的部分予以刪除 /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' | sed 's/Bcast.*$//g' 這樣就把IP地址截取出來了。 直接修改文件內容(慎重) 1、sed -i '$a #This is a test' test.txt 說明: 命令的執行結果是在test.txt最后一行加入“This is a test” 由于$代表的是最后一行,而a的操作是新增,因此該文件最后新增。 awk 功能:awk是一個數據處理工具。相比于sed常常用于一整行的處理,awk則比較傾向于將一行分成數個“字段”來處理。因此,awk相當 適合處理小型數據的數據處理。 基本語法: awk [options] 'program' FILE ... program:PATTERN {ACTION STATEMENTS} 多個語句之間用分號分隔 print,printf 選項: -F:指明輸入時用到的字段分隔符; -v var=value:自定義變量; 1、print print item1, item2, ... 要點: (1)逗號分隔符; (2)輸出的各item可以是字符串,也可以是數值;當前記錄的字段、變量或awk的表達式; (3)如省略item,相當于print $0; 2、變量 (1)內建變量 FS:input field seperator,輸入分隔符,默認為空白字符; OFS:output field seperator,輸出分隔符,默認為空白字符; RS:input record sepeator,輸入時的換行符; ORS:output record seperator,輸出時的換行符; NF:number of field,字段數量 {print NF}, {print $NF} NR:number of record,行數; FNR:各文件分別計數;行數; FILENAME:當前文件名; ARGC:命令行參數的個數; ARGV:數組,保存的是命令行所給定的各參數; (2)自定義變量 -v var=value 變量名區分字符大小寫 在program中直接定義 3、printf命令 格式化輸出:printf FORMAT, item1, item2, ... (1)FORMAT必須給出; (2)不會自動換行,需要顯式給出換行控制符,\n (3)FORMAT中需要分別為后面的每個item指定一個格式化符號; 格式符: %c:顯示字符的ASCII碼; %d,%i:顯示十進制整數; %e,%E:科學計數法數值顯示; %f:顯示為浮點數; %g,%G:以科學計數或浮點形式顯示數值; %s:顯示字符串; %u:無符號整數; %%:顯示%自身; 修飾符: #[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度; %3.1f -:左對齊 +:顯示數值的符號 4、PATTERN (1)empty:空模式,匹配每一行; (2)/regular expression/:僅處理能夠被此處模式匹配到的行; (3)relational expression:關系表達式;結果有“真”有“假”;結果為“真”才會被處理 真:結果為非0值,非空字符串; (4)line ranges:行范圍, startline,endline:/pat1/,/pat2/ 注意:不支持直接給出數字的格式 (5)BEGIN/END模式 BEGIN{}:僅在開始處理文件中的文本之前執行一次; END{}:僅在文本處理完成之后執行一次; 5、常用的action (1)Expressions (2)Control statements:if,while等; (3)Compound statements:組合語句; (4)input statements (5)output statements 6、控制語句 (1)if-else 語法:if(condition) statement [else statement] 使用場景:對awk取得的整行或某個字段做條件判斷; 示例: awk -F: '{if($3>=500) {printf "Common user:%s\n",$1} else {printf "root or Sysuser:%s\n",$1}}' /etc/passwd awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd awk '{if(NF>5) print $0}' /etc/fstab df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}' (2)while循環 語法:while(condition) statement 條件 “真”,進行循環;條件“假”,退出循環; 使用場景:對一行內的多個字段逐一類似處理時使用;對數組中的各元素逐一處理時使用; 示例: awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7){print $i,length($i)}; i++}}' /etc/grub2.cfg (3)do-while循環 語法:do statement while(condition) 意義:至少執行一次循環體 (4)for循環 語法:for(expr1;expr2;expr3) statement for(variable assignment;condition;iteration process){for-body} 示例: awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($i)}}' /etc/grub2.cfg 特殊用法: 能夠遍歷數組中的元素; 語法:for(var in array){for-body} (5)switch語句 語法:switch(expression) {case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP2/:statement;...;default:statement} (6)next 提前結束對本行的處理而直接進入下一行; 示例: awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd 7、array 關聯數組:array[index-expression] index-expression: (1)可使用任意字符串,字符串要使用雙引號; (2)如果某數組元素事先不存在,在引用時,awk會自動創建此元素,并將其值初始化為“空串”; 若要判斷數組中是否存在某元素,使用“index in array”格式進行; weekdays[mon]="Monday" 若要遍歷數組中的每個元素,要使用for循環; for(var in array){for-body} 示例: awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays){print weekdays[i]}}' 8、其它常見示例 (1)統計/etc/fstab文件中每個文件系統類型出現的次數; awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab (2)統計/etc/fstab文件中每個單詞出現的次數; awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
2、刪除/boot/grub/grub.conf文件中所有行的行首的空白字符;
[root@localhost ~]# sed 's/^[[:space:]]*//g' /boot/grub/grub.conf
3、刪除/etc/fstab文件中所有以#開頭,后跟至少一個空白字符的行的行首的#和空白字符;
[root@localhost ~]# sed 's/^#[[:space:]]\+//' /etc/fstab
4、把/etc/fstab文件的奇數行另存為/tmp/fstab.3;
[root@localhost ~]# sed 'n;d' /etc/fstab > /etc/fstab.3
5、echo一個文件路徑給sed命令,取出其基名;進一步地,取出其路徑名;
[root@localhost ~]# echo "/etc/sysconfig/network/" | sed -r 's@^/.*/([^/]+)/?@\1@g' [root@localhost ~]# echo "/etc/sysconfig/network/" | sed 's#[^/]\+/\?$##'
6、統計指定文件中所有行中每個單詞出現的次數;
[root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
7、統計當前系統上所有tcp連接的各種狀態的個數;
[root@localhost ~]# netstat -tan | awk 'FNR>2{print $NF}' | sort | uniq -c
8、統計指定的web訪問日志中各ip的資源訪問次數:
[root@localhost ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
9、寫一個腳本:定義一個數組,數組元素為/var/log目錄下所有以.log結尾的文件的名字;顯示每個文件的行數;
[root@localhost ~]# vim line.sh #!/bin/bash test=`ls /var/log/*log` for i in $test do wc -l $i done
10、寫一個腳本,能從所有同學中隨機挑選一個同學回答問題;進一步地:可接受一個參數,做為要挑選的同學的個數;
[[root@localhost ~]# vim student.sh #!/bin/bash stu=(zhangsan lisi wangwu zhaoliu liuhu zhaosi) i=$[$RANDOM % ${#stu[@]}] echo ${stu[i]} [root@localhost ~]# vim students.sh #!/bin/bash stu=(zhangsan lisi wangwu zhaoliu liuhu zhaosi) read -p "Please input the number of students:" num if [[ $num -le ${#stu[@]} ]] then for ((i=0;i<num;i++)) do x=$[$RANDOM % ${#stu[@]}] echo ${stu[$x]} stu[$x]=${stu[${#stu[@]}-1]} unset stu[${#stu[@]}-1] done else echo "input error!" fi
11、授權centos用戶可以運行fdisk命令完成磁盤管理,以及使用mkfs或mke2fs實現文件系統管理;
[root@localhost ~]# vim /etc/sudoers centos ALL=(root) NOPASSWD: /sbin/fdisk, /sbin/mke2fs, /sbin/mkfs
12、授權gentoo用戶可以運行邏輯卷管理的相關命令;
[root@localhost ~]# vim /etc/sudoers gentoo ALL=(root) lvm
13、基于pam_time.so模塊,限制用戶通過sshd服務遠程登錄只能在工作時間進行;
[root@localhost ~]# vim /etc/pam.d/sshd account required pam_time.so [root@localhost ~]# vim /etc/security/time.conf *;*;*;MoTuWeThFr0900-1800#表示工作時間9點到下午6點允許訪問ssh
14、基于pam_listfile.so模塊,定義僅某些用戶,或某些組內的用戶可登錄系統;"
[root@localhost ~]# vim /etc/sshd_userlist root centos gentoo [root@localhost ~]# chmod 600 /etc/sshd_userlist [root@localhost ~]# chown root /etc/sshd_userlist [root@localhost ~]# vim /etc/pam.d/sshd 添加 auth required pam_listfile.so item=user sense=allow file=/etc/sshd_userlist onerr=succeed
原創文章,作者:N21-天天,如若轉載,請注明出處:http://www.www58058.com/61536