shell字串匹配的實現

2021-10-11 21:26:04 字數 4075 閱讀 5233

一、簡介

bash shell提供了很多字串和檔案處理的命令。如awk、expr、grep、sed等命令,還有檔案的排序、合併和分割等一系列的操作命令。grep、sed和awk內容比較多故單獨列出,本文只涉及字串的處理和部分文字處理命令。

二、字串處理

1、expr命令

expr引出通用求值表示式,可以實現算術操作、比較操作、字串操作和邏輯操作等功能。

(1)計算字串長度

字串名為string,可以使用命令$或expr length $string兩種方法來計算字串的長度。若string包括空格,需用雙引號引起來(expr length後面只能跟乙個引數,string有空格會當作多個引數處理)。

(2)子串匹配索引

expr的索引命令格式為:expr index $string $substring(子串),在字串$string上匹配$substring中字元第一次出現的位置,匹配不到,expr index返回0。

"wo"在字串string中雖然出現在第7,但還是返回o首次出現的位置5。

(3)子串匹配的長度

expr match $string $substring,在string的開頭匹配substring字串,返回匹配到的substring字串的長度,若string開頭匹配不到則返回0,其中substring可以是字串也可以是正規表示式。

"world"儘管在string**現,但是未出現在string的開頭處,因此返回0。

(4)抽取子串

bash shell提供兩種命令#和expr實現抽取子串功能。

其中#有兩種格式。

格式一:#從名稱為$string的字串的第$position個位置開始抽取子串,從0開始標號。

格式二:#增加$length變數,表示從$string字串的第$position個位置開始抽取長度為$length的子串。

(都是從string的左邊開始計數抽取子串)

#還提供了從string右邊開始計數抽取子串的功能。

格式一:#,冒號與橫槓間有乙個空格

格式二:#

expr substr也能夠實現抽取子串功能,命令格式:expr substr $string $position $length,與#最大不同是expr substr命令從1開始進行標號。

接著使用正規表示式抽取子串的命令,但只能抽取string開頭處或結尾處的子串。

抽取字串開頭處的子串,格式一:expr match $string ' $substring '。格式二:expr $string : ' $substring ',其中冒號前後都有乙個空格。

抽取字串結尾處的子串,格式一:expr match $string '.* $substring '。格式二:expr $string : '.* $substring '。.*表示任意字元的任意重複。

(5)刪除子串

刪除字串是指將原字串中符合條件的子串刪除,命令只有$格式。

從string開頭處刪除子串,格式一:$,刪除開頭處與substring匹配的最短子串。格式二:$刪除開頭處與substring匹配的最長子串。其中substring並非是正規表示式而是萬用字元。

從string結尾處開始刪除,格式一:$,刪除結尾處與substring匹配的最短子串。格式二:$刪除結尾處與substring匹配的最長子串。與上述命令僅在#和%之間不同。

(5)替換子串

替換子串命令都是$,可以在任意處、開頭處、結尾處替換滿足條件的子串。其中的substring都不是正規表示式而是萬用字元。

在任意處替換子串命令,格式一:$,僅替換第一次與substring相匹配的子串。格式二:$,替換所有與substring相匹配的子串。

在開頭處替換與substring相匹配的子串,格式為:$。

在結尾除替換與substring相匹配的子串,格式為:$。

三、對檔案的排序、合併和分割

文字處理命令包括sort命令、uniq命令、join命令、cut命令、paste命令、split命令、tr命令和tar命令,它們實現對檔案記錄排序、統計、合併、提取、貼上、分割、過濾、壓縮和解壓縮等功能,它們與sed和awk構成了linux文字處理的所有命令和工具。

(1)sort命令

sort命令是一種對文字排序的工具,它將輸入檔案看做由多條記錄組成的資料流,而記錄由可變寬度的字段組成,以換行符作為定界符。sort命令格式:sort [選項] [輸入檔案]

sort命令預設的域分隔符是空格符,-t選項可用於設定分隔符。sort -t: test中-t與":"之間是沒有空格的。未指定-t分隔符是空格符,這時記錄內開頭與結尾的空格都將被忽略,如(空格):root:(空格)則只有乙個域,-t:指定冒號則這條記錄就包含了三個域。

sort命令預設是按第1個域進行排序的,也可以通過-k選項指定某個域進行排序。例如:sort -t: -k3 test。

sort命令-n選項可以指定根據數字大小進行排序(不按字母順序排序)。

sort命令-r選項用於將排序結果逆向顯示,如使用-n按數字從小到大排序後,使用-r選項將結果逆向顯示。

sort命令-u選項去掉排序結果中的重複行。

sort命令-o選項加上檔名將結果儲存到另乙個檔案中(sort預設將排序後的結果輸出到螢幕上)。

sort命令-m選項將兩個排好序的檔案合併成乙個排好序的檔案,在檔案合併前它們必須已經排好序。-m選項對未排序的檔案合併是沒有任何意義的。

sort和awk都是分域處理檔案的工具,兩者結合起來可以有效地對文字塊進行排序。

(2)uniq命令

uniq命令用於去除文字檔案中的重複行,類似sort -u,但uniq命令去除的重複行必須是連續重複出現的行,中間不能夾雜任何其他文字行,而sort -u命令使所有的重覆記錄都被去掉。

uniq命令有3個選項:

uniq -c test,列印每行在文字中重複出現的次數。

(3)join命令

join命令用於實現兩個檔案中記錄的連線操作,將兩個檔案中具有相通域的記錄選擇出來,再將這些記錄所有的域放在一行(包含來自兩個檔案的所有域)。如join -t: a.txt b.txt,將a.txt和b.txt具有共同域的記錄連線到一起。

join命令的結果預設是不顯示這些未進行連線的記錄,-a和-v選項用於顯示這些未進行連線的記錄,-a1和-v1指顯示檔案1中未連線的記錄,而-a2和-v2指顯示檔案2中的未連線記錄。-a與-v的區別是:-a顯示以共同域進行連線的結果和未進行連線的記錄,而-v則不顯示以共同域進行連線的記錄。

join命令預設顯示連線記錄在兩個檔案中的所有域,而且按順序。-o選項用於改變結果顯示的格式,可以指定顯示哪幾個域、按什麼順序顯示這些域。例如:join -t: -o1.1 2.2 1.2 a.txt b.txt,其中-o1.1 2.2 1.2表示顯示格式依次顯示第1個檔案中的第1個域、第2個檔案中的第2個域、第1個檔案中的第2個域,結果顯示三個域。

join -t: -i -1 3 -2 1 a.txt b.txt,檔案1的第3個域和檔案2的第1個域進行連線,-i忽略大小寫。join命令在對兩個檔案進行連線時,兩個檔案必須都是按照連線域排好序的。

(4)cut命令

cut -c1-5 a.txt,提取a.txt的第1~5個字元。-c有三種表示方式:-cn表示第n個字元、-cn,m表示第n個字元和第m個字元、-cn-m表示第n個字元到第m個字元。-c是按字元提取文字的,無須使用-d改變域分隔符,-f按域提取文字時就需要使用-d設定域分隔符了。-f同樣也可以用三種方式指定域數或域範圍。

cut可以靈活提取文字檔案中的內容,預設將提取內容放在標準輸出上,也可以使用檔案重定向來將內容儲存到檔案。

(5)paste命令

paste命令用於將文字檔案或標準輸出中的內容貼上到新的檔案,它可以將來自不同檔案的資料貼上到一起,形成新的檔案。paste命令格式:paste [選項] file1 file2,其選項如下:

paste file1 file2,貼上file1和file2,file1在前,將file1的內容作為每行記錄的第1域、file2的內容作為第2域。可以使用-d設定域分隔符paste -d: file1 file2。

paste命令預設是將乙個檔案按列貼上的,-s選項可以實現將乙個檔案按行貼上。

ls | paste -d" " - - - -,從標準輸入中讀取資料時"-"選項才起作用,"-"表示讀取1次標準輸入資料即讀取到標準輸入資料中的乙個域,- - - - 每行顯示4個檔名。

Shell字串匹配

方法一 網上看到這兩個方法,貌似有些問題 echo line grep e repeat test eq 0 echo yes echo no 用 e還是 q需要驗證 echo line grep q repeat 這個貌似 test eq 0 echo yes echo no 這個沒有搞懂 這個是...

實現樸素的字串匹配

實現函式int findsubstr char t,char p 相關知識 在乙個長字串中尋找乙個短字串出現的位置,這是字串匹配問題。例如 長字串是 string 短字串是 ring 那麼短字串在長字串 現的位置是 2 即 ring 在 string 現的開始位置是 2 include includ...

字串匹配的python實現

所有字串匹配演算法的核心問題是,當出現不匹配時,如何向後移動模式串 一 暴力匹配演算法 如果要匹配乙個字串s 和乙個模式串p,則從i 0開始依次匹配s i i len p 簡單粗暴,如下 def matcher t,p param t the string to check param p patt...