日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shell-awk详细笔记

發布時間:2024/7/5 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shell-awk详细笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
shell# var="hexiaoqiang"# ${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,并將其全部替換為SUBSTI所表示的字符串;${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,將其替換為SUBSTI所表示的字符串;${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,將其替換為SUBSTI所表示的字符串;notice:PATTERN中使用glob風格和通配符;查找刪除:${var/PATTERN/SUBSTI}:以PATTERN為模式查找var字符串中第一次的匹配,并刪除之;${var//PATTERN}:以PATTERN為模式查找var字符串中的匹配,并全部刪除;${var/#PATTERN}:以PATTERN為模式查找var字符串行首的匹配,并全部刪除;${var/%PATTERN}:以PATTERN為模式查找var字符串中的匹配,并全部刪除;${var/%PATERN}:以PATTERN為模式查找var字符串末尾的匹配,并刪除之;字符串大小寫轉換:${var^^}:把var中的所有的小寫字符轉換為大寫${var,,}:把var中的所有大寫字符轉換為小寫;變量賦值:${var:-VALUE}:如果var變量為空,或未設置,那么返回value;否則,則返回var變量的值;${var:=VALUE}:如果var變量為空,或未設置,那么返回VALUE,并將VALUE賦值給var變量;否則,則返回var變量的值;${var:+VALUE}:如果var變量不空,則返回VALUE;${var:?ERRROR_INFO}:如果var為空,或未設置,那么返回ERROR_INFO為錯誤提示;否則,返回var值;練習:寫一個腳本,完成如下功能(1)提示用戶輸入一個可執行命令的名稱;(2)獲取此命令所依賴的所有庫文件列表;(3)復制命令至某目標目錄(例如/mnt/sysroot,即把此目錄當作根)下的對應的路徑中bash,/bin/bash ==> /mnt/sysroot/bin/bashuseradd,/usr/sbin/useradd ==> /mnt/sysroot/lib64/ld-linux-x8664.so.2進一步:每次復制完成一個命令之后,不要退出,而是提示用戶繼續輸入要復制的其它命令,并重復完成如上所描述的功能;知道用戶輸入"quit"腳本 bash特性:引用命令的執行結果:$(COMMAND) 或者 `` 反引號示例: mkdir $(date +%H-%M-%s)stat:查看文件或者文件系統的狀態示例: stat /etc/fstabFile: ‘/etc/fstab’Size: 465 Blocks: 8 IO Block: 4096 regular fileDevice: fd00h/64768d Inode: 33554498 Links: 1Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2018-11-28 18:16:42.497510412 +0800Modify: 2018-11-17 23:20:14.801999430 +0800Change: 2018-11-17 23:26:58.495992201 +0800Birth: -linux 文件包含2類屬性:元數據: metadata數據:date正則匹配:[[:upper:]] 所有的大寫字母匹配[[:lower:]] 所有的小寫字母匹配[[:alpha:]] 所有字母匹配[[:digit:]] 所有數字匹配[[:alnum:]] 所有字母數字匹配[[:space:]] 所有空白字符匹配[[:punct:]] 所有標點符號匹配[^] 匹配直指定范圍外的單個字符[^[:upper]] 匹配任意大寫字母之外的單個字符[^0-9][^[:alnum:]] 匹配非數字字母之外的單個字符 IO重定向及管理程序:指令+數據程序:IO程序的數據流有三種:輸入的數據流: <----- 標準輸入(stdin), 鍵盤輸出的數據流: -----> 標準輸出(stdout), 顯示器錯誤輸出流: -----> 錯誤輸出(stderr), 顯示器fd: file descriptor 文件描述符標準輸入 0標準輸出 1錯誤輸出 2輸出重定向 >特性 覆蓋輸出>>特性 追加輸出set -C 禁止覆蓋輸出重定向向至已存在的文件此時可使用強制覆蓋輸出 >|set +C關閉上述特性 這個效果僅對當前shell有效錯誤輸出流重定向:2> , 2>>合并正常輸出流和錯誤輸出流 &> , &>>COMMAND > /PATH/TO/SOMEFILE 2>&1COMMAND >> /PATH/TO/SOMEFILE 2>&1----這個地方不太理解 要反復練習理解輸入重定向 <tr命令tr [option] ... SET1 [SET2]把輸入的數據當中的字符,凡是在set1定義范圍內出現的,通通對位轉換為set2出現的字符用法1: tr set1 set2 < /path/from/somefile用法2: tr -d set1 < /path/from/somefile以上2中操作都不修改源文件Here Document : <<cat << EOFcat > /path/to/somefile << EOF 這個知識點很重要 很多次都沒有理解 管道:鏈接程序,實現將前一個命令的輸出直接定向后一個程序當做輸入數據流COMMAND1 | COMMAND2 | COMMAND3 | ... tee 命令:COMMAND | tee /PATH/TO/SOMEFILE 既可以輸出查看的文件 又保存至其他位置#!/bin/bash#cat << EOF disk) show disks infomem) show memory infocpu) show cpu info*)QUITEOFread -p "Your choice: " optionif [[ "$option" == "disk" ]];thenfdisk -l /dev/[sh]d[a-z]elif [[ "$option" == "mem" ]];thenfree -melif [[ "$option" == "cpu" ]];thenlscpuelseecho "Unkown option"exit 3fi#!/bin/bash#for username in user21 user22 user23;douseradd $usernamedone#求100以內所有正整數之和#!/bin/bashdeclare -i sum=0for i in {1..100};doecho "\$sum is $sum , \$i is $i"sum=$[$sum+$1]doneawk命令:FS 默認的內置輸入變量 默認為空白字符 如果在awk命令行重新定義 只需要-v 定義就可以了 示例:awk -v FS=':' '{print $1}' /etc/passwd 指的是以 : 為分隔符好進行打印awk -v FS=':' '{print "hello:",$1}' /etc/passwd上面的2條命令也可以通過-F:就可以是分隔符為:號進行打印的需求了awk -F: '{print "hello\ world:\ ",$1}' /etc/passwdOFS 內置的輸出變量符 默認為空白字符 可以自定義FS OFS 區別主要是輸入判斷的變量符號 和輸出表現的變量符號 比較容易理解示例awk -v FS=':' -v OFS=':' '{print $1,$3,$7}' /etc/passwdRS: input record seperator 輸入時的換行符ORS: output record seperator 輸出時的換行符示例:awk -v RS=' ' -v ORS='#' '{print}' /etc/passwdawk -v RS=' ' -v ORS='#' '{print}' /var/log/messages解釋:輸入的時候以空格為換行符 然后輸出的時候 有空格的時候就會轉換為#號 這個地方不好理解NF: number of field 字段數量 記錄每行以默認空格計算有多少字段示例:awk '{print NF}' /etc/log/messagesawk '{print NF}' /etc/passwd$NF: NF會得到每行以空格計算有多好字段 然后拿到這個字段數 然后打印這個字段的值取字段變量的最后一個值示例:awk '{print $NF}' /var/log/messages awk 內部引用變量不需要加$ 直接引用即可 NR: 記錄文件的行數 后面跟多個文件的時候 繼續增加行數 而是不區分文件進行計數示例:awk '{print NR}' /etc/passwdawk '{print NR}' /var/log/messages /etc/passwdawk -F: '(NR>=2&&NR<=10) {print $1}' /etc/passwdFNR: awk后面跟多個文件的時候 分別記錄文件的行數 示例:awk '{print FNR}' /etc/fstab /etc/passwdFILENAME 顯示文件名 一個文件要是有多少行 就會顯示多少遍示例:awk '{print FILENAME}' /etc/fstab /etc/passwd 不建議常用 但是思想是可以遍歷文件多少行 每行都會處理ARGC: 命令行參數的個數示例:awk '{print ARGC}' /etc/passwd /etc/issue /etc/fstab 記錄命令行參數的個數 awk和自己的參數算只能算一個 文件有多少行就會顯示多少遍awk 'BEGIN{print ARGC}' /etc/passwd /etc/fstab /etc/issue 在打印前面加BEGIN就會只顯示一遍ARGV: 數組,保存的是命令行所給定的各參數示例:awk '{print ARGV[0]}' /etc/passwd /etc/fstab /etc/issue 只會打印awk這個下標的數組 不加BEGIN的時候文件有多少行就會顯示多少遍awk 'BEGIN{print ARGV[0],ARGV[1],ARGV[2],ARGV[3]}' /etc/passwd /etc/fstab /etc/issue /var/log/messages 在前面print添加BEGIN之后就只顯示一遍 根據下標打印相對應的數組值 2.2自定義變量-v var=value變量名區分大小寫在program中直接定義示例:awk -v test="hello world" '{print test}' /etc/fstab awk -v test="hello world" 'BEGIN{print test}' /etc/fstabprint 打印變量的時候直接引用變量名 /etc/fstab 這個地方值利用的是行數 文件有多少行就會打印多少遍hello world 前面加BEGIN的時候只會打印一遍了awk '{test="hello world";print test}' 可以在print中直接定義變量awk 'BEGIN{test="hello world";print test}' /etc/fstab 2.3 printf 命令格式化輸出: printf FORMAT,item1,item2,...FORMAT必須給出printf不會自動換行,需要顯示給出換行控制符,\nFORMAT 中需要分別為后面的每個item指定一個格式化符號格式符:%c: 顯示字符的ASCII碼%d %i: 顯示十進制整數 decimal intege 單詞可能不太準確%e %E: 科學計數法數值顯示%f: 顯示為浮點數%g %G: 以科學計數法或浮點形式顯示數值%s: 顯示字符串%u: 無符號整數%%: 顯示%自身示例:awk -F: '{printf "%s",$1}' /etc/passwd 把$1套到%s進行以字符串進行顯示 默認不加換行符就會顯示在一行中awk -F: '{printf "%s\n",$1}' /etc/passwd \n就會每一行只顯示一個用戶名awk -F: '{printf "Username: %s\n",$1}' /etc/passwd 還可以加前綴提示字符進行顯示awk -F: '{printf "Username: %s,UID: %i\n",$1,$3}' /etc/passwdawk -F: '{printf "Username: %s,UID: %i\n",$1,$3}' /etc/passwd 第一個%s后面不能加\n不然每一行都會在2行進行顯示了 在最后一個FORMAT定義的變量之后加\n符號 這個是顯示 用戶名和UID %d %i 都是以數值的方式顯示用戶的UID修飾符:#[.#]:第一個數字控制顯示的寬度;第二個#表示小數點后的精度;%3.1f 默認這樣的使用 以f居多默認對齊方式為右對齊示例:awk -F: '{printf "Username: %15s,UID: %d\n",$1,$3}' /etc/passwd -: 表示左對齊示例:awk -F: '{printf "Username: %-15s,UID: %d\n",$1,$3}' /etc/passwd+: 顯示數值的符號 正數的時候前面會有+號示例:awk -F: '{printf "Username: %15s,UID: %+d\n",$1,$3}' /etc/passwd 4.操作符算數操作符x+y, x-y, x*y, x/y, x^y[x的y次方], x%y[取模] -x+x:轉換為數值 [把字符串轉換為數值]字符串操作符:沒有符號的操作符,表示字符串連接賦值操作符:=,+=,-=, *=, /=, %=, ^=++, --比較操作符:>, >=, <, <=, !=, ==模式匹配符:~:左側的字符是否能匹配右側的字符!~:左側的字符不匹配右側的字符邏輯操作符:&& 與|| 或! 非函數調用:定義函數 后面跟上()就可以了 ()里面可以加上調用的參數function_name(argu1,argu2,argu2,...)條件表達式:selector:條件挑選器?:表示為真執行 if-true-expression否則執行 if-false-expression示例:selector?if-true-expression:if-false-expressionawk -F: '{$3>1000?usertype="Common User":usertype="System or Systemuser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd解釋:-F: 定義打印格式 $3>1000 判斷第三個字段是否大于1000 然后定義條件表達式 格式上面有解釋,以:為分隔符進行判斷 第一個為真后面就會打印 第二個為假后面會打印 字段使用雙引號進行包含 printf 開始匹配打印 "15%s:%-s\n" printf的打印格式 %s默認為右對齊 15表示15個空格 %-s表示左對齊 $1是取字段第一個值 usertype是調用定義的變量字符串進行打印 后面是需要的條件輸入文件位置 5、PATTERN(1) empty:孔模式,匹配每一行(2) /regular expression/:僅處理能夠被此處的模式匹配到的行(3) relational expression:關系表達式:結果有"真"有"假":結果為"真"才會被處理;真:結果為非0值,非空字符串(4) line ranges:行范圍startline,endline: /pat1/,/pat2/注意:不支持直接給出數字的格式示例:awk '/^UUID/{print $1}' /etc/fstab 在這兒就能實現UUID匹配行的打印 打印第一個字段 默認的變量還是以空格為分割awk '!/^UUID/{print $1}' /etc/fstab 打印匹配模式以外的行 然后打印第一個字段awk -F: '$3>100{print $1,$3}' /etc/passwd $3>100是進行模式匹配 然后再后面打印 就可以實現類似grep的功能了awk -F: '$3>100{printf "%15s:%-s\n",$1,$3}' /etc/passwdawk -F: '$3<100{printf "%15s:%-s\n",$1,$3}' /etc/passwdawk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd 查找/etc/passwd中shell為/bin/bash的用戶awk -F: '$NF~/bash$/{print $1,$NF}' /etc//passwd $NF模式匹配 ~進行模式匹配 匹配的內容要用//括起來 /bash$/以bash結尾的用戶awk -F: '$NF!~/bash$/{print $1,$NF}' /etc//passwd 不以/bash$/結尾的在$NF后面加一個!就可以awk -F: '/^r/,/^s/{print $1}' /etc/passwd /pat1/,/pat2/ 模式匹配 從r字母開頭的行匹配到s開頭的行結束awk -F: 'BEGIN{print " username uid \n---------------"}{print $1,$3}' /etc/passwd BEGIN 和 END的使用方法awk '/^[[:space:]]*linux16/{print}' /etc/grub2.cfg 打印這個文件中以開頭為空格的字符 然后后面匹配Linux16的行(5) BEGIN / END 模式BEGIN{}: 僅在開始處理文件中的文本之前執行一次;END{}:僅在文本處理完成之后執行一次;示例:awk -F: '{print " username uid \n---------------"}{print $1,$3}END{print "=====================\n end"}' /etc/passwd END用在最后進行使用 打印結尾 表示 6. 常用的action(1) Expressions(2) Control statements: if while等:(3) Compound statements:組合語句(4) input statements(5) output statements 7. 控制語句if(condition) {statements}if(condition) {statements} else {statements}while(condition) {statements}do {statements} while{condition}for(expr1;expr2;expr3) {statements}breakcontinuedelete array[index]delete arrayexit{statements}7.1 if-else語法:if(condition) {statements} else {statements} 使用場景:對awk取得的整行或某個字段做條件判斷示例: awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwdawk -F: '{if($3>100) print $1,$3}' /etc/passwdawk -F: '{if($3>100) {printf "Common user: %s\n",$1} else {printf "root or Systemuser: %s\n",$1}}' /etc/passwdif-else的時候要把{prinf}都用大括號個括住了 不然會報語法錯誤awk '{if(NF>5) print $0}' /etc/fstab 對字段數大于5的進行printdf -Th | awk -F[%] '/^\/dev/{print $1}' | awk '{if($NF>4) print $1}'7.2 while 循環示例:awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfgawk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7) print $i,length($i);i++}}' /etc/grub2.cfg 嵌套if循環判斷7.3 do-while循環語法:do statement while(condition)意義:至少執行一次循環體7.4 for循環語法: for(expr1;expr2;expr3) statementfor(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}7.5 switch語句語法: switch(expression) {case VALUE1 or /REGEXP1/: statement;case VALUE2 or /REGEXP2/: statement;...;default: statement}7.6 break和continuebreak [n] 退出n層循環continue7.7 next提前結束對本行的處理而直接進入下一行;示例:awk -F: '{if($3%2!=0) next; print $1,$3}' /etc//passwd 8.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"]="moday";weekdays["tue"]="Tuesday"; for(i in weekdays) {print weekdays[i]}}'注意: var會遍歷array的每個索引使用場景:統計打印結果中某個字符串出現的次數netstat -ntlp | awk '/^tcp\>/{state[$NF]++}END { for(i in state) {print i.state[i]}}'awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log 統計ip訪問的次數 俗稱報告生成器awk '/^UUID/{fs[$3]++}END{for(i in fs) {print i,fs[i]}}' /etc/fstab 統計系統文件類型出現的次數awk '{for(i=1;i<NF;i++){count[$i]++}}END{for(i in count) {print i,count[i]}}' /etc/fstab 統計文件單詞出現的次數{for(i=1;i<NF;$i++){count[$i]++}} 使用for循環做定義判斷 NF記錄的是文件字段出現的次數 count[$i]++ 則是使用$i下標進行統計次數 每次+1 9.函數9.1內置函數函數處理;rand();返回0和1直接的隨機數 awk在系統第一次打印時 是隨機的而后的打印都是保持第一次的隨機數字符串處理;length([s]): 返回指定字符串的長度sub(r,s,[t]): 以r表示的模式來查找t所表示的字符中的匹配的內容,并將其第一次出現替換為s所表示的內容 這個只會替換第一次替換不會 全局進行替換gsub(r,s,[t]):表示全局進行替換示例:awk -F: '{print sub(o,O,$1)}' /etc/passwd 使用print的時候會打印結果1表示不成功 0表示成功split(s,a,[r]) : 以r為字符切割字符s,并將切割后的結果保存至a所表示的數組中示例:netstat -tan | awk '/^tcp/{split($5,ip,":");count[ip[1]]++}END{for(i in count) {print i,count[i]}}'詳解: {split($5,ip,":")} 以第5個字段進行切割保存至ip數組中,":"以分隔符進行切割ip[1] 是以":"切割之后拿到左面第一個字段的值count[ip[1]]++ 拿到左面第一個字段下表的記錄 每次都+1 做數組循環{split($5,ip,":");count[ip[1]]++}END最后只打印一次{for(i in count) {print i,count[i]}} 做數組循環判斷進行打印結果

?

轉載于:https://www.cnblogs.com/S--S/p/10177047.html

總結

以上是生活随笔為你收集整理的shell-awk详细笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。