實用bash命令記錄
本篇文章記錄工作中比較實用,能減輕工作量的bash命令。
1.字符串截取
假設有這麼一個變量silo=/home/liujiacai/codes/cascalog/silo,那麼
${silo##/*/}=silo ${silo#/*/}=liujiacai/codes/cascalog/silo
##表示取後麵字符串最長的那段;#表示取最短的那段,這兩個是從前麵刪除的
${silo%%/*/}=/home/liujiacai/codes/cascalog/silo ${silo%%/*}= (空) ${silo%/*}=/home/liujiacai/codes/cascalog
%%和##功能相同,不過這個是從後麵開始刪的。第一個什麼也沒刪除是因為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
2.正則表達式
以前在做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的特殊字符
擴展正則表達式的特殊字符 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文件就是使用的這種字符串匹配模式
詳情參見:https://en.wikipedia.org/wiki/Glob_(programming)
3.find命令
find path [-name] pattern 在path路徑下查找名字為pattern的文件,返回基於path的相對路徑
find . -type f -exec file '{}' \;這條命令查找當前目錄下的文件,並且作為file命令的參數執行。{}表示當前文件名,用單引號是防止{}被shell解釋器解釋為shell script punctuation,分號用反斜線也是這樣目的,也可以用單引號代替反斜線。
find $HOME -mtime 0查找$HOME文件夾下在24小時之內修改過的文件。這裏用0是因為-mtime選項對於每個文件的修改時間取其除以24後的商,餘數舍棄。
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \ -print -prune這個命令是用來查看項目的是否有.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了。
4.xargs
這個命令在管道中特別有用
find /tmp -name core -type f -print | xargs /bin/rm -f這條命令查找/tmp文件夾下名為core的文件,並且把它刪除。這時的文件名中不能有空格、換行符,解決方法是加上 -0參數。
當然上麵這條命令還可以這麼寫:
find /tmp -depth -name core -type f -delete利用find的參數-delete選項,這樣比用xargs效率更高,因為這樣不用再調用 fork(2) and exec(2) 來launch rm和xargs進程。
這裏的-depth選項指明“先處理文件夾中的內容在處理文件夾本身”,-delete本身就暗含了-depth選項。
<span >cut -d: -f1 < /etc/passwd | sort | xargs</span>這條命令用於顯示passwd文件中記錄的當前係統的用戶。
需要注意的時,xargs並不能一定保證,命令正確執行,有可能xargs後麵的命令在接受管道前麵的輸入時,係統執行其他命令,改變了xargs的輸入。
5. bash中的比較
bash中有個test命令可以進行一係列的測試,man 一下可以看到解釋為" check file types and compare values",具體語法為
test EXPRESSION其實我們最常用的是test的一個別名"[",沒錯,就是左方括號,語法為
[ EXPRESSION ]
EXPRESSION後麵的右方括號是作為結束隻用,沒什麼實際含義.
如果忽略EXPRESSION,那麼返回false. 常用的EXPRESSION有如下這麼幾個:
( EXPRESSION ) EXPRESSION is true 需要注意一點的是,括號"(",")"需要用"\"轉義 ! EXPRESSION EXPRESSION is false EXPRESSION1 -a EXPRESSION2 both EXPRESSION1 and EXPRESSION2 are true EXPRESSION1 -o EXPRESSION2 either EXPRESSION1 or EXPRESSION2 is true -n STRING the length of STRING is nonzero.STRING equivalent to -n STRING -z STRING the length of STRING is zero STRING1 = STRING2 the strings are equal STRING1 != STRING2 the strings are not equal INTEGER1 -eq INTEGER2 INTEGER1 is equal to INTEGER2 INTEGER1 -ge INTEGER2 INTEGER1 is greater than or equal to INTEGER2 INTEGER1 -gt INTEGER2 INTEGER1 is greater than INTEGER2 INTEGER1 -le INTEGER2 INTEGER1 is less than or equal to INTEGER2 INTEGER1 -lt INTEGER2 INTEGER1 is less than INTEGER2 INTEGER1 -ne INTEGER2 INTEGER1 is not equal to INTEGER2 FILE1 -ef FILE2 FILE1 and FILE2 have the same device and inode numbers FILE1 -nt FILE2 FILE1 is newer (modification date) than FILE2 FILE1 -ot FILE2 FILE1 is older than FILE2 -d FILE FILE exists and is a directory -e FILE FILE exists
test的這些Express和我們平常用的C/Java語言係列的判斷不一樣(比如需要對一些字符進行轉義),這點讓我們很不是適應,不過幸好,bash提供了補救方案,那就是"[[",使用"[["可以對文件名和字符串使用更自然的語法。可以用括號和邏輯操作符把 test 命令支持的測試組合起來。下麵給出一個示例:
使用 [[ 複合命令,這裏不再需要對"("與")"進行轉義
[[ ( -d "$HOME" ) && ( -w "$HOME" ) ]] && echo "home is a writable directory"
參考:
https://www.ibm.com/developerworks/cn/linux/l-bash-test.html
最後更新:2017-04-03 12:54:36