1. 正則表達式及其應用
正則表達式(英語:Regular Expression,常簡寫爲regex、regexp或RE),又稱正則表示式、正則表示法、規則表達式、常規表示法。正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。在很多文本編輯器裏,正則表達式通常被用來檢索、替換那些符合某個模式的文本。
Linux中很多命令都支持正則表達式,比如接下來要提到的grep命令,而接下來我們要講的內容也將以grep命令結合正則表達式,來充分介紹一些常用的用法。
正則表達式有兩種:標準正則表達式和擴展正則表達式。
正則表達式的元字符從功能上可以分爲以下四類:字符匹配,次數匹配,位置錨點,分組和邏輯組合。以下也將逐一介紹。
補充:
許多程序設計語言都支持利用正則表達式進行字符串操作。例如,在Perl中就內建了一個功能強大的正則表達式引擎。正則表達式這個概念最初是由Unix中的工具軟件(例如sed和grep)普及開的。
最初的正則表達式出現於理論計算機科學的自動控制理論和形式化語言理論中。在這些領域中有對計算(自動控制)的模型和對形式化語言描述與分類的研究。
1940年,沃倫·麥卡洛克與Walter Pitts將神經系統中的神經元描述成小而簡單的自動控制元。
1950年代,數學家斯蒂芬·科爾·克萊尼利用稱之爲“正則集合”的數學符號來描述此模型。肯·湯普遜將此符號系統引入編輯器QED,隨後是Unix上的編輯器ed,並最終引入grep。自此以後,正則表達式被廣泛地應用於各種Unix或類Unix系統的工具中。正則表達式的POSIX規範,分爲基本型正則表達式(Basic Regular Expression,BRE)和擴展型正則表達式(Extended Regular Express,ERE)兩大流派。在兼容POSIX的UNIX系統上,grep和egrep之類的工具都遵循POSIX規範,一些數據庫系統中的正則表達式也符合POSIX規範。grep、vi、sed都屬於BRE,是歷史最早的正則表達式,因此元字符必須轉譯之後才具有特殊含義。egrep、awk則屬於ERE,元字符不用轉譯。
補充2:
1.1 正則表達式中字符匹配
1.1.1 匹配任意字符
.
可以匹配任意的單個字符、英文字母、數字,以及他本身。
.
可以連續使用,比如我們可以寫出..m..
這樣一個正則表達式,他將匹配所有:前面有任意兩個字符,後面緊跟着一個m,又隨後跟着任意兩個字符的文本。
1.1.2 匹配.
元字符怎麼辦?
有時候我不想讓.
去匹配任意字符,只想匹配自身就好,該怎麼辦呢?
此時,可以使用\.
來對其進行轉義。
例如:\.com
會匹配.com,而不會匹配1com、2com
補充:
如果要匹配
\
可以使用\\
來對其進行轉義
1.2 匹配字符組
我們瞭解.
可以匹配幾乎所有的單個字符,但有的時候我們只想要匹配幾個有限字符中的某一個,就無需用到它了,這時候我們可以使用字符組來匹配。
假設有這樣一種情況,我們希望匹配兩個單詞,比如hero和here,即her後面要麼出現o要麼出現e,其他的情況都不需要,那該怎麼辦呢?
正則表達式提供了字符組來解決這個問題,當遇到這重her後面只想匹配o或者e的情況,它的語法是[oe]
,[]
中括號是特殊標記,可以劃定屬於組內的字符的界定。因此[oe]
所代表的含義是:“匹配e或者o” 。
補充:
字符組雖然由多個字符構成,但對於正則表達式來說,他只匹配“單個”字符,而字符組能夠匹配的單個字符,即是他定義中的字符(
[]
內的字符)。[]
本身不進行字符匹配,他僅僅劃定字符組的邊界。
1.2.1 字符組中的字符區間
假設我們要匹配一組文件,其命名方式爲:a1,a2,a3…a9,根據前面介紹的方式,我們可以寫出a[123456789]
這樣的正則表達式,這樣確實能夠達到我們想要的結果,但如果需要匹配的範圍在大點呢,比如:a1,b1,c1…z1,我們如果把26個英文字母塞進正則表達式中就太麻煩了,有沒有更好的方法呢?
毫無疑問,正則表達式提供了字符區來簡化這一過程,他的語法是起始字符-結束字符對於上面的例子,我們可以用[1-9]和[a-z]
來解決。
補充:
如果要在
[]
中匹配-
需要用到轉義字符\-
而在[]
以外,-
變成了一個普通字符,無需在進行轉義。
1.2.2 反義字符組
有時候我們需要匹配一些“除某些字符以外”的其他字符,這時候,我們可以使用反義字符,他的用法是[^字符合集]
以上面的例子爲例,我們只想匹配除:a1,a2,a3以外的文件,這時我們可以這樣寫正則表達式:a[^1-3]
1.3 匹配多個字符
上面的知識中,我們可以知道,無論簡單也好,複雜也好,他們都只是匹配單個字符,如果要匹配多個字符,而組成這個字符串的每個字符都比較複雜的情況下,我們該如何讓我們的正則表達式正確的發揮作用?
1.3.1 匹配一個或多個
正則表達式中,可以在單個字符、字符組、特定字符類型、單個任意字符後面加一個+
來匹配一個或多個字符組成的字符串
1.3.2 一些有用的元字符
. |
代表任意單個字符 |
---|---|
[] |
指定範圍內的字符,[hero] 表示h,e,r,o這4個字母 |
[^] |
排除[] 中字符以外的字符,[^hero] 表示除h,e,r,o這4個字母 |
[:alnum:] |
代表大小寫字母和數字 |
[:alpha:] |
代表大小寫字母 |
[:lower:] |
代表小寫字母 |
[:blank:] |
代表空格和TAB |
[:digit:] |
所有單個空字符 |
[:graph:] |
所有單個非空字符 |
[:print:] |
代表可打印的字符 |
[:punct:] |
代表標點符號 |
1.3.3 正則表達式中的次數匹配
在處理文本時,有時候需要指定某個內容出現的具體次數,這時候就要用到一些特殊的元字符
* |
代表匹配*前面的字符出現了任意次,也可以是0次 |
---|---|
\? |
代表匹配其前面的字符1次或者0次 |
\+ |
代表匹配其前面的字符大於等於1次 |
\{n\} |
代表匹配其前面的字符連續出現n次,n是數字 |
\{m,n\} |
代表匹配其前面的字符次數要大於等於m,小於n次 |
\{m,\} |
代表匹配其前面的字符次數最少出現m次 |
\{,n\} |
代表匹配其前面的字符小於等於n次 |
1.3.4 正則表達式的位置錨點
對文本處理時,常想表示指定字符出現的位置,比如行首,行尾,詞首,詞尾等。那麼以下的元字符可以幫到你。
^ |
行首錨定 |
---|---|
$ |
行尾錨定 |
^PATTERN$ |
精確匹配整行 |
^$ |
空行 |
^[[:space:]]*$ |
空白行 |
\< 或 \b |
詞首錨點 |
\> 或 \b |
詞尾錨點 |
\<PATTERN\> |
匹配整個單詞 |
1.3.5 擴展正則表達式的使用
普通的正則表達式不錯是不錯,就是轉義符要輸入太多了,看起來不是非常美觀,所以,纔有了擴展的正則表達式,能夠讓表達式看起來更直觀一些;
? |
代表匹配1次或者多次 |
---|---|
+ |
代表匹配1次或0次 |
{m} |
代表匹配m次 |
{m,n} |
代表最少匹配m次最多匹配n次 |
() |
分組符號 |
| |
或邏輯符號 |
grep -E |
實現支持擴展正則表達式 |
2. Linux用戶和組的權限管理
linux是一個多用戶的操作系統,即同一個時間允許多個用戶同時使用。爲了實現不同的用戶可以設置不同的權限,需要針對每個不同的權限的用戶創建對應的用戶賬號,而爲了管理起來更加方便,可用將用戶加入到組中。此外用戶必須要有一個組,此組成爲用戶的主組,用戶也可以再加入到其他組中,此組稱爲附屬組或附加組。
2.1 查看用戶信息文件
Linux系統中每個用戶都有一個唯一的用戶編號與其對應,我們將其稱爲UID(User IDentifier)在Linux中區分不同的用戶就是通過UID來實現的,而非我們習慣以爲的用戶名。每個登錄用戶的基本信息保存在/etc/passwd
中,每一行都存放了對應的用戶信息。
[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
...
我們拿出第一行來說說吧:
root:x:0:0:root:/root:/bin/bash
通過冒號分開的內容分別爲:
root |
用戶名 |
---|---|
x |
早期時這個位置是存放密碼的,後來基於安全考慮,密碼轉移至/etc/shadow 中了 |
0 |
表示用戶編號,UID,此處的0代表爲超級用戶 |
0 |
此處表示組編號,GID |
root |
此處是用戶的說明信息位置 |
/root |
表示此用戶的家目錄位置 |
/bin/bash |
表示此用戶的默認shell類型 |
3. 一些用戶管理的常用命令
groupadd
語法
groupadd
命令 語法格式如下:
groupadd [-g gid [-o]] [-r] [-f] group
參數說明:
- -g:指定新建工作組的 id;
- -r:創建系統工作組,系統工作組的組ID小於 500;
- -K:覆蓋配置文件 “/ect/login.defs”;
- -o:允許添加組 ID 號不唯一的工作組。
- -f,–force: 如果指定的組已經存在,此選項將失明瞭僅以成功狀態退出。當與 -g 一起使用,並且指定的GID_MIN已經存在時,選擇另一個唯一的GID(即-g關閉)。
useradd
語法
useradd [-mMnr][-c <備註>][-d <登入目錄>][-e <有效期限>][-f <緩衝天數>][-g <羣組>][-G <羣組>][-s <shell>][-u <uid>][用戶帳號]
或
useradd -D [-b][-e <有效期限>][-f <緩衝天數>][-g <羣組>][-G <羣組>][-s <shell>]
參數說明:
-
-c<備註> 加上備註文字。備註文字會保存在passwd的備註欄位中。
-
-d<登入目錄> 指定用戶登入時的起始目錄。
-
-D 變更預設值.
-
-e<有效期限> 指定帳號的有效期限。
-
-f<緩衝天數> 指定在密碼過期後多少天即關閉該帳號。
-
-g<羣組> 指定用戶所屬的羣組。
-
-G<羣組> 指定用戶所屬的附加羣組。
-
-m 自動建立用戶的登入目錄。
-
-M 不要自動建立用戶的登入目錄。
-
-n 取消建立以用戶名稱爲名的羣組.
-
-r 建立系統帳號。
-
-s 指定用戶登入後所使用的shell。
-
-u 指定用戶ID。
userdel
語法
userdel [-r][用戶帳號]
參數說明:
- -r 刪除用戶登入目錄以及目錄中所有文件。
usermod
語法
usermod [-LU][-c <備註>][-d <登入目錄>][-e <有效期限>][-f <緩衝天數>][-g <羣組>][-G <羣組>][-l <帳號名稱>][-s <shell>][-u <uid>][用戶帳號]
參數說明:
- -c<備註> 修改用戶帳號的備註文字。
- -d登入目錄> 修改用戶登入時的目錄。
- -e<有效期限> 修改帳號的有效期限。
- -f<緩衝天數> 修改在密碼過期後多少天即關閉該帳號。
- -g<羣組> 修改用戶所屬的羣組。
- -G<羣組> 修改用戶所屬的附加羣組。
- -l<帳號名稱> 修改用戶帳號名稱。
- -L 鎖定用戶密碼,使密碼無效。
- -s 修改用戶登入後所使用的shell。
- -u 修改用戶ID。
- -U 解除密碼鎖定。
4. 一些練習
1、顯示/etc目錄下,以非字母開頭,後面跟了一個字母以及其它任意長度任意字符的文件或目錄
ls -d /etc/[^[:alpha:]][[:alpha:]]*
2、複製/etc目錄下所有以p開頭,以非數字結尾的文件或目錄到/tmp/mytest1目錄中。
#分析:本題有兩個需求,一個是要有一個目錄/tmp/mytest1,一個是複製/etc下所有p開頭的且以非數字結尾的文件,匹配的正則表達式爲:p*[^[:digit:]]
mkdir /tmp/mytest1
cp -r /etc/p*[^[:digit:]] /tmp/mytest1/
#也可以組合一下
mkdir /tmp/mytest1 && cp -r /etc/p*[^[:digit:]] /tmp/mytest1/
3、將/etc/issue文件中的內容轉換爲大寫後保存至/tmp/issue.out文件中
#分析:將大象放進冰箱要幾步?
#分析:1.先把/etc/issue文件內容提取出來,2.轉成大寫,3.寫入/tmp/issue.out中
cat /etc/issue |tr 'a-z' 'A-Z' > /tmp/issue.out
#知識點:cat、tr、|、>
4、請總結描述用戶和組管理類命令的使用方法並完成以下練習:
(1)、創建組distro,其GID爲2019;
#知識點:groupadd
groupadd distro -g 2019
(2)、創建用戶mandriva, 其ID號爲1005;基本組爲distro;
#知識點:useradd
useradd mandriva -u 1005 -g distro
(3)、創建用戶mageia,其ID號爲1100,家目錄爲/home/linux
#知識點:useradd
useradd mageia -u 1100 -d /home/linux
(4)、給用戶mageia添加密碼,密碼爲mageedu,並設置用戶密碼7天后過期
#知識點:passwd
echo "mageedu" |passwd -x 7 --stdin mageia
彩蛋:mageia
Mageia 是一個非營利組織及其主導的Linux發行版的名稱。
Mageia是Mandriva Linux於2010年9月形成的分支,它由那份來自法國的頗受歡迎的Linux發行的前僱員及貢獻者們創建。與Mandriva這份商業實體所不同的是,Mageia計劃乃是一個社區項目及一個非盈利性組織,它的目標是開發一套自由的基於Linux的操作系統
“Mageia”一詞出自希臘語“μαγεία”,在英語中對應爲"magic",即“魔術”。之所以取這一名稱,靈感來自魔術師 Leon Mandrake 的名字,而 Mandrake 也是 Mandriva Linux 發行版的原名。
(5)、刪除mandriva,但保留其家目錄;
#知識點:userdel
userdel mandriva
#userdel默認不刪除家目錄
彩蛋:mandriva
Mandriva S.A. 是一間法國的軟件公司,企業總部位於巴黎,研發總部位於巴西庫裏奇巴。他們創造了Mandriva Linux,並負責維持與研發。
它的前身是創建於1998年的MandrakeSoft。
(6)、創建用戶slackware,其ID號爲2002,基本組爲distro,附加組peguin;
#知識點:group useradd
#首先要創建一個組:peguin
groupadd peguin
#創建用戶指定ID 基本組 附加組
useradd -u 2002 -g distro -G peguin slackware
彩蛋:slackware
Slackware是Slackware Linux, Inc的[Patrick Volkerding](http://en.wikipedia.org/wiki/Patrick Volkerding)製作的Linux發行版本。Slackware走了一條與其他的發行版本(Red Hat、Debian、Gentoo、SuSE、Mandriva、Ubuntu等)不同的道路,它力圖成爲“UNIX風格”的Linux發行版本。它的方針是隻吸收穩定版本的應用進程,並且缺少其他Linux版本中那些爲發行版本定製的配置工具。
(7)、修改slackware的默認shell爲/bin/tcsh;
#知識點:usermod
usermod -s /bin/tcsh slackware
(8)、爲用戶slackware新增附加組admins;
#知識點:groupadd usermod
groupadd admins
usermod -G admins slackware