最近一段時間一直在學習算術運算和正則表達式以及條件判斷,連續看了四五遍,基本概念已經能夠搞清楚了,實際操作中容易把正則表達式和算術運算以及條件判斷混淆.看來還是要勤加聯繫.今天終於是有勇氣來總結這兩週的學習.在這之前,因爲在練習這些邏輯概念性的知識經常會用到grep命令.首先介紹一下grep.
格式:grep [options] 'PATTERN' file,...
grep: 文本搜索工具,根據用戶指定的文本模式對目標文件進行逐行搜索,顯示文件中能夠被模式所匹配到的行.
模式PATTERN:指的是使用算術運算,正則表達式,或條件判斷按組合成的字符串規則,按照這個規則在文件中查找是否有符合條件的行,簡單來講就是按照一定規則輸出文件中匹配這個規則的內容.
#grep --color=auto Boot /etc/rc.d/rc.sysinit ##顯示/etc/rc.d/rc.sysinit文件中匹配Boot字符的行,匹配的字符選擇以--color=auto選項的紅色樣式輸出
grep 常用選項:
--color=auto:查找到的字符串顯示顏色
-v: 反向,顯示不能被模式所匹配到的行;(用在排除法)
#grep -v 'root' /etc/passwd #排除空白行後輸出結果
-o: 僅顯示被模式匹配到的字串,而非整行;
-i: 不區分字符大小寫, ignore-case
-E: 支持擴展的正則表達式
-A #:不但顯示匹配到的行,還顯示下面的#行
-B #: 不但顯示匹配到的行,還顯示前面的#行
-C #: 不但顯示匹配到的行,還顯示上下各#行
正則表達式:是一類字符所書寫出的模式(pattern),元字符不表示字符本身的意義,用於額外功能性的描述(類似文件名通配符).分爲基本正則表達式和擴展正則表達式
基本正則表式的元字符:(grep -E支持擴展正則表達式)
字符匹配符:
.: 任意單個字符
[]: 指定範圍內的任意單個字符:數字[0-9], [[:digit:]];字母[a-z], [[:lower:]];大寫字母[A-Z],:upper:]];不區分大小寫字母[[:alpha:]];數字和字母[[:alnum:]];空格[[:space:]];標點符號[[:punct:]]
[^]:指定範圍外的任意單個字符:[^1-8]結果就爲0,9
#grep --color=auto '[Rr]..[Tt]' /etc/passwd ##[Rr]起始中間任意兩個字符[Tt]結尾
#grep --color=auto '[Rr].*[Tt]' /etc/passwd ##[Rr]起始中間任意個字符[Tt]結尾
#grep --color=auto '[Rr][^[:punct:]].[Tt]' /etc/passwd ##[Rr]起始中間一個非符號字符和一個任意字符[Tt]結尾
次數匹配符:用來指定匹配其前面的字符的次數
*: 前面一個字符匹配任意次. 例:x*y 匹配 xxy, xy, y, (*表示X可以出現任意次都匹配)
.*: 匹配任意長度的任意字符
\?: 匹配前一個字符0次或1次,
x\?y 匹配 xy, y, xxy
\{\}因爲在正則表達式中,是儘可能長的去匹配字符;所以在特定匹配次數情況下要用{}.
\{m\}: 匹配m次
\{m,n\}:至少m次,至多n次
\{m,\}: 至少m次;
\{0,n\}:可以有可以沒有至多n次;
位置錨定符:用於指定字符出現的位置
^: 錨定行首,在行首出現的字符,在字符左側,以^開始爲標識^Char (行首帶Char的字符).
#grep --color=auto '^[Rr][^[:punct:]].[Tt]' /etc/passwd ##/etc/passwd文件中以大小寫r開頭跟一個非符號字符和一個任意字符以大小寫t結束的四字字符串
$: 錨定行尾,在行尾出現的字符,在字符右側,以$結束爲標識,char$(行尾爲Char結尾).
#grep --color=auto 'bash$' /etc/passwd ##以精確查找/etc/passwd文件an中bash結尾的行
^$: 空白行,行首和行尾之間沒有任何字符.所以是空白行
#grep '^$' /etc/rc.d/rc.sysinit | wc -l ##查找rc.sysinit中的空白行並通過管道輸出給wc命令統計行數
\<|\b:\<或者\b 錨定詞首:查找以模式爲詞首的單詞
#grep --color=auto '\<[Rr][^[:punct:]].[Tt]' /etc/passwd ##passwd中以[Rr]開頭的單詞
\>|\b:\>或者\b錨定詞尾,查找以模式爲詞首的單詞
\<***\>:錨定詞首和詞尾組合可以精確匹配單詞,或精確字符序列
分組:多個字符的組合的模式:
\(\)
#\(ab\)*xy ##任意個ab帶xy字符,xy前後字符一致 錯誤的是ab*xy只匹配a和任意個b帶xy的字符
引用:對分組的字符進行位置參數進行引用
\1: 後向引用,引用模式中前面的第一個左括號以及與之對應的右括號中的模式所匹配到的內容
\2: 後向引用,引用模式中前面的第二個左括號以及與之對應的右括號中的模式所匹配到的內容
\(a.b\)xy\1: a6bxya6b, (\1前面匹配到什麼後面也要引用什麼 a6bxya7b就不匹配)
#匹配grep.txt中匹配字符兩種不同方式的不同:
He like his lover.
She love her liker.
He love his lover.
She like her liker. ##保存到grep.sh
#grep --color=auto 'l..e.*l..er' grep.sh ## l..e都會匹配到,沒有引用所以按字符匹配
#grep --color=auto '\(l..e\).*\1r' grep.sh ## love對lover,like對liker,有引用,所以前後字符會對引用內容精確匹配!
egrep: 和grep命令使用差不多,使用擴展正則表達來構建模式,相當於grep -E .這裏就把不同的地方提出來
次數匹配:
?: 匹配其前面的字符0或1次;不用加\號
+: 匹配其前面的字符至少1次
{m}: 匹配其前面的字符m次;用法一樣也是不用加\號
{m,n}: 至少m次,至多n次
{m,}: 至少m次;
{0,n}:至多n次;
錨定:
\<, \b: 詞首單詞的這兩個還是要加\號
\>, \b:詞尾
分組:
(): 分組,用法一樣也是不用加\號
|: 或者,grep沒有的功能 整串擴展選擇,擴展的內容最好用(),不加括號是對|左右兩側的整個字符串進行選擇
grep -E "con(C|c)at" ##結果爲conCat或concat
grep -E "conC|cat" ##結果爲conC或cat
PS:在grep和egre使用中在很多地方例如:(),{},<>,?等符號需要根據使用不同命令或選項,加或者不加\轉譯符,以示這裏是做正則表達式的作用,不然會被系統認作其它意義的符號,一定要記清楚,經常出錯都是在轉譯符的不當使用.
shell的算數運算:還是先來說一說常用的命令
declare:申明一個變量爲整數並初始化變量. -i:整型變量 #declare -i varName=0
let:執行算數表達式,結果必須保存在變量中!
let varName=算術表達式
例: #num1=4
#num2=7
#let sum=$num1+$num2
#let er=$num2/num1
varName=$[算術表達式] (可以獲得結果,可以不用些let)
例: #mul=$[$num1*$num2] (不用寫let)
varName=$((算術表達式))
算數操作符:
+加, -減, *, /, %取餘,bash不能執行浮點運算,如果計算中存在小數,將會被圓整,小數部分會被丟棄!
+=, -=, *=, /=, %=:對自己進行運算並賦值給自己,如果一個變量的數值取出之後就不再使用,只需要保存計算後的值,可以將計算後數值又保存回這個變量可以節省內存.
#totalweight=40
#totalweight=$[$totalweight+2] ##把變量totalweight加2在賦值給這個變量,表達式本身就是進行運算後再賦值給自己,所以可以不用申明
#let totalweight+=2 ##totalweight+=2本身不是變量賦值,所以需要let申明運算後賦值給自身.
++ -- 自加1自減1
#let totalweight++ ##先引用變量再計算
#let ++totalweight ##先計算在引用變量
相比較來說算術運算和正則表達式是比較枯燥的內容,而且需要不斷練習去理解每種結構的邏輯才能保證不會錯誤書寫錯誤,本來想把條件測試的內容寫到一起,發現條件判斷內容也是非常的多,所以還是放到下一篇博客來專門寫!這些內容在書寫格式上和邏輯要有許多相近的地方特別容易搞錯,多花些心思.勤練習,不放棄!每次能夠寫一個小小的腳本也是很有成就感的.
最後還是在博客的最後放一些練習題,看一次練一次.熟能生巧!
練習:計算100以內所有正整數之和
練習:分別計算100以內所有偶數之和和奇數之和;
練習:計算/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/issue三個文件的字符數之和;
練習:計算當前系統所有用戶的ID之和;
練習:新建用戶tmpuser1-tmpuser10,並計算他們的id之和;
練習: 寫一個腳本,用鍵盤隨意輸入兩個數,計算兩者和商積差.
練習:通過鍵盤給定一個目錄路徑,默認爲/,來判斷目錄下文件內容的類型;
練習:顯示/proc/meminfo文件中以大小寫s開頭的行;
練習:取出默認shell爲非bash的用戶;
練習:取出默認shell爲bash的且其ID號最大的用戶;
練習:顯示/etc/rc.d/rc.sysinit文件中,以#開頭,後面跟至少一個空白字符,而後又有至少一個非空白字符的行;
練習:顯示/boot/grub/grub.conf中以至少一個空白字符開頭的行;
練習:找出/etc/passwd文件中一位數或兩位數;
練習:找出ifconfig命令結果中的1到255之間的整數;
練習:查看當前系統上root用戶的所有信息;
練習:添加用戶bash和testbash、basher,而後找出當前系統上其用戶名和默認shell相同的用戶;
練習:找出netstat -tan命令執行的結果中以“LISTEN”或“ESTABLISHED”結尾的行;
練習:取出當前系統上所有用戶的shell,要求:每種shell只顯示一次,且按升序顯示;
練習:寫一個腳本,分別統計/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件中各自以#開頭的行的行數,以及空白行的行數;
練習:寫一個腳本,分別複製/etc/rc.d/rc.sysinit、/etc/init.d/functions和/etc/fstab文件至/tmp目錄中,文件名爲原名後跟上當前的日期組成;
例如第一個文件複製後的名稱爲/tmp/rc.sysinit-2-14-02-16;
練習:寫一個腳本顯示當前系統上所有默認shell爲bash的用戶的用戶名、UID以及其在/etc/passwd文件中的行號;