天天看點

實用bash指令記錄

本篇文章記錄工作中比較實用,能減輕工作量的bash指令。

假設有這麼一個變量silo=/home/liujiacai/codes/cascalog/silo,那麼

##表示取後面字元串最長的那段;#表示取最短的那段,這兩個是從前面删除的

%%和##功能相同,不過這個是從後面開始删的。第一個什麼也沒删除是因為silo最後一個字元為‘o’不是‘/’,是以不變

 bash shell可以進行變量的條件替換,既隻有某種條件發生時才進行替換

 ${foo:-word}  

當沒有foo變量時,傳回word

${foo:=word}

當沒有foo變量時,傳回word,并且把word指派給foo變量

 ${foo:+word}  

當定義了foo變量時,傳回word

${foo:?msg}

當沒有foo變量時,把msg送到标準錯誤輸出

${foo:offset:length} 

length可以為空

${#foo}

變量foo字元個數

 ${foo/pattern/string}

字元串替換,最短原則

 ${foo//pattern/string}

字元串替換,最長原則

如果foo=aabbbbbbbcc,那麼

echo ${foo//bb/dd}傳回aaddddddbcc

echo ${foo//bb/dd}傳回aaddbbbbbcc

以前在做java開發時也無數次遇到re(regex expression),每次看我都以為我懂了,直到今天我才算是明白,我掌握的知識永遠是那麼冰山一角。扯蛋完畢。

warning:正規表達式和通配符(wildcard)不一樣。

正規表達式分基本re與擴充re之分,bash中有個指令預設隻認識基本的,比如grep,但是通過-e參數就能識别擴充的了;有的可以認識擴充,這點一定要搞清楚。

在基本表達式中有這麼幾個特殊字元,一定要記住

基本正規表達式的特殊字元

re字元

含義與範例

^word

待搜尋的字元串(word)必須在行首

word$

待搜尋的字元串(word)必須在行尾

.

代表任意一個字元

\

轉移符,将有特殊符号的特殊意義去掉

*

重複前一個字元,一次或多次。warn:這裡和通配符中*含義不同

\{n,m\}

連續n到m個的“前一個重複字元”

[word]

[]内的字元集合中任取一個字元 h[io]t  代表的是hit或者hot;其次是[0-9]、[a-z]等這種用法; 再其次是[^word],表示不含“w”、“o”、“r”、“d”中的字元

再說說擴充re的特殊字元

擴充正規表達式的特殊字元

+

重複前一個字元一次或一次以上,比如go+d,,可以表示god、good、goood等等

重複前一個字元零次或一次,比如go?d,表示gd、god

|

表示或的意思,比如'gd|good',表示取gd或者good

()

分組處理字元,比如'g(la|oo)d',可以表示glad或者good

再提醒一次,“!”歎号在正規表達式中并不是特殊字元。

unix-like系統還存在一類字元串比對機制--globbing,在globbing中,*和通配符的用法是一樣的,代表零個或多個任意字元。git的.gitignore檔案就是使用的這種字元串比對模式

find path [-name] pattern  在path路徑下查找名字為pattern的檔案,傳回基于path的相對路徑

這條指令查找目前目錄下的檔案,并且作為file指令的參數執行。{}表示目前檔案名,用單引号是防止{}被shell解釋器解釋為shell script punctuation,分号用反斜線也是這樣目的,也可以用單引号代替反斜線。

查找$home檔案夾下在24小時之内修改過的檔案。這裡用0是因為-mtime選項對于每個檔案的修改時間取其除以24後的商,餘數舍棄。

這個指令是用來檢視項目的是否有.svn與.git與cvs目錄的,-o 是-or的簡寫,表示前面的指令為false時才執行,{}表示目前處理的檔案夾名,-prune選項可以防止不必要的嵌套查找,假設repo有如下目錄結構:

repo/project1/cvs

repo/gnu/project2/.svn

repo/gnu/project3/.svn

repo/gnu/project3/src/.svn

repo/project4/.git

帶上-prune選項後就不會再搜尋project3/.src目錄了,因為已經找到了project3/.svn了。

這個指令在管道中特别有用

這條指令查找/tmp檔案夾下名為core的檔案,并且把它删除。這時的檔案名中不能有空格、換行符,解決方法是加上 -0參數。

當然上面這條指令還可以這麼寫:

利用find的參數-delete選項,這樣比用xargs效率更高,因為這樣不用再調用 fork(2) and exec(2) 來launch rm和xargs程序。

這裡的-depth選項指明“先處理檔案夾中的内容在處理檔案夾本身”,-delete本身就暗含了-depth選項。

這條指令用于顯示passwd檔案中記錄的目前系統的使用者。

需要注意的時,xargs并不能一定保證,指令正确執行,有可能xargs後面的指令在接受管道前面的輸入時,系統執行其他指令,改變了xargs的輸入。

bash中有個test指令可以進行一系列的測試,man 一下可以看到解釋為" check file types and compare values",具體文法為

其實我們最常用的是test的一個别名"[",沒錯,就是左方括号,文法為

expression後面的右方括号是作為結束隻用,沒什麼實際含義.

如果忽略expression,那麼傳回false. 常用的expression有如下這麼幾個:

test的這些express和我們平常用的c/java語言系列的判斷不一樣(比如需要對一些字元進行轉義),這點讓我們很不是适應,不過幸好,bash提供了補救方案,那就是"[[",使用"[["可以對檔案名和字元串使用更自然的文法。可以用括号和邏輯操作符把 test 指令支援的測試組合起來。下面給出一個示例:

使用 [[ 複合指令,這裡不再需要對"("與")"進行轉義

參考:

http://www.ibm.com/developerworks/cn/linux/l-bash-test.html