Shell編程之變量的高級用法詳解
變量替換
語法 | 說明 |
${變量名#匹配規(guī)則} | 從變量開頭進(jìn)行規(guī)則匹配,將符合最短的數(shù)據(jù)刪除 |
${變量名##匹配規(guī)則} | 從變量開頭進(jìn)行規(guī)則匹配,將符合最長的數(shù)據(jù)刪除 |
${變量名%匹配規(guī)則} | 從變量尾部進(jìn)行規(guī)則匹配,將符合最短的數(shù)據(jù)刪除 |
${變量名%%匹配規(guī)則} | 從變量尾部進(jìn)行規(guī)則匹配,將符合最長的數(shù)據(jù)刪除 |
${變量名/舊字符串/新字符串} | 變量內(nèi)容符合就字符串,則第一個舊字符串會被新字符串替換 |
${變量名//舊字符串/新字符串} | 變量內(nèi)容符合就字符串,則全部的舊字符串會被新字符串替換 |
示例
var1="hello world hello world" # 所謂最長和最短其實就是正則表達(dá)式中的貪婪模式和非貪婪模式 # 刪除匹配規(guī)則為*lo的數(shù)據(jù)(開頭最短刪除) echo ${var1#*lo} -> world hello world # 刪除匹配規(guī)則為*lo的數(shù)據(jù)(開頭最長刪除) echo ${var1##*lo} -> world # 刪除匹配規(guī)則為hel*的數(shù)據(jù)(尾部最短刪除) echo ${var1%hel*} ->hello world # 刪除匹配規(guī)則為hel*的數(shù)據(jù)(尾部最長刪除) echo ${var1%%hel*} -> # 替換第一個舊字符串world為Beijing echo ${var1/world/Beijing} ->hello Beijing hello world # 替換第一個舊字符串world為Beijing echo ${var1/world/Beijing} ->hello Beijing hello Beijing
變量測試
變量置換方式 | 變量y沒有設(shè)置 | 變量y為空值 | 變量y設(shè)置值 |
x=${y-新值} | x=新值 | x為空 | x=$y |
x=${y:-新值} | x=新值 | x新值 | x=$y |
x=${y+新值} | x為空 | x=新值 | x=新值 |
x=${y:+新值} | x為空 | x為空 | x=新值 |
x=${y=新值} | x=新值 | x為空 | x=$y |
y=新值 | y值不變 | y值不變 | |
x=${y:=新值} | x=新值 | x=新值 | x=$y |
y=新值 | y=新值 | y值不變 | |
x=${y?新值} | 新值輸出到標(biāo)準(zhǔn)錯誤輸出(屏幕) | x為空 | x=$y |
x=${y:?新值} | 新值輸出到標(biāo)準(zhǔn)錯誤輸出 | 新值輸出到標(biāo)準(zhǔn)錯誤輸出 | x=$y |
- 如果大括號內(nèi)沒有":",則變量 y 為空或沒有被設(shè)置,處理方法是不同的;如果大括號內(nèi)有":",則變量 y
- 不論是為空,還是沒有被設(shè)置,處理方法是一樣的;
- 如果大括號內(nèi)是"-“或”+",則在改變變量 x 的值的時候,變量 y 的值是不改變的;
- 如果大括號內(nèi)是"=",則在改變變量 x 的值的同時,變量 y 的值也會改變;
- 如果大括號內(nèi)是"?",則當(dāng)變量 y 不存在或為空時,會把"新值"當(dāng)成報錯輸出到屏幕上。
示例
# x=${y-新值} echo ${y=$var1} ->hello world hello world y= echo ${y-$var1} -> y=hello Beijing echo ${y-$var1} ->hello Beijing # x=${y:-新值} echo ${y:-$var1} ->hello world hello world y= echo ${y:-$var1} ->hello world hello world y=hello Beijing echo ${y:-$var1} ->hello Beijing # x=${y+新值} echo ${y+$var1} -> y= echo ${y+$var1} ->hello world hello world y=hello Beijing echo ${y+var1} ->hello world hello world # x=${y:+新值} echo ${y:+$var1} -> y= echo ${y:+$var1} -> y=hello Beijing echo ${y:+var1} ->hello world hello world # x=${y=新值} x=${y=$var1} echo $x ->hello world hello world echo $y ->hello world hello world y= x=${y=$var1} echo $x -> echo $y -> y=hello Beijing x=${y=$var1} echo $x ->hello world hello world echo $y ->hello Beijing # x=${y:=新值} x=${y:=$var1} echo $x ->hello world hello world echo $y ->hello world hello world y= x=${y:=$var1} echo $x ->hello world hello world echo $y ->hello world hello world y=hello Beijing x=${y:=$var1} echo $x ->hello Beijing echo $y ->hello Beijing # x=${y?新值} echo ${y?$var1} ->-bash: y: hello world hello world y= echo ${y?$var1} -> y=hello Beijing echo ${y?$var1} ->hello Beijing # x=${y:?新值} echo ${y?$var1} ->-bash: y: hello world hello world y= echo ${y:?$var1} ->-bash: y: hello world hello world y=hello Beijing echo ${y:?$var1} ->hello Beijing
看完了我還是記不?。?!參考上表吧!
字符串處理
字符串長度
語法 | 說明 | |
方法一 | ${#string} | 無 |
方法二 | expr length "$string" | string有空格,則必須加雙引號 |
示例
# 方法一 var1="hello world" echo ${#var1} ->11 # 方法二 len=`expr length "$var1"` echo $len ->11 ## var1有空格,必須加雙引號,否則報錯 expr: syntax error ## var2沒有空格,可以不需要加雙引號 var2=hello expr length $var2 5
子串字符索引
語法 | expr index $string $substring | string/substring有空格,則必須加雙引號 | 此方法并不是查找子串的索引位置,它會把子串進(jìn)行字符拆分,哪個字符最先找到了則返回其索引位置。并且索引從1開始 |
expr index "$var1" llo ->3 expr index "$var1" lole ->2
子串長度
語法 | expr match $string substring | string/substring有空格,則必須加雙引號 |
expr match "$var1" hel ->3 expr match "$var1" llo ->0
expr match $string substring獲取子串長度必須是從頭開始匹配
抽取子串
語法 | 說明 | |
方法一 | ${string:position} | 從string中的position開始抽取子串 |
方法二 | ${string:position:length} | 從string中的position開始,抽取長度為length的子串 |
方法三 | ${string: -position} | (注意-position前有個空格)從尾部開始的position抽取子串 |
方法四 | ${string:(position)} | 從string中的頭部開始的position抽取子串 |
方法五 | expr substr $string $position $length | 從string中的position開始,抽取長度為length的子串 |
示例
# 方法一 echo ${var1:2} ->llo world # 方法二 echo ${var1:2:5} ->llo w # 方法三 echo ${var1: -2} ->ld echo ${var1: -2:1} ->l # 方法四 echo ${var1:(3)} ->lo world echo ${var1:(3):2} ->lo echo ${var1:(-2):1} ->l # 方法五 expr substr "$var1" 2 5 ->ello
注意:expr substr $string $position $length的position從1開始,而${string:position:length}的從0開始。
var2=hello echo ${var2:2:5} ->llo expr substr $var2 2 5 ->ello
小試牛刀
需求描述:變量string="Bigdata process framework is Hadoop,Hadoop is an open source project."執(zhí)行腳本后,打印輸出string字符串變量,并給出用戶一下選項:
- 打印string長度
- 刪除字符串中所有的Hadoop
- 替換第一個Hadoop為Mapreduce
- 替換所有Hadoop為Mapreduce
用戶輸入數(shù)字1|2|3|4,可以執(zhí)行對應(yīng)項的功能;輸入q|Q則退出交互模式。
#!/bin/bash string="Bigdata process framework is Hadoop,Hadoop is an open source project." function print_tips { echo "==============================" echo "1->打印string長度" echo "2->刪除字符串中所有的Hadoop" echo "3->替換第一個Hadoop為Mapreduce" echo "4->替換所有Hadoop為Mapreduce" echo "q|Q->退出" echo "==============================" } function len_of_string { echo "${#string}" } function del_hadoop { echo "${string//Hadoop/}" } function rep_first_hadoop_mapreduce { echo "${string/Hadoop/Mapreduce}" } function rep_all_hadoop_mapreduce { echo "${string//Hadoop/Mapreduce}" } while true do echo "" echo "" echo "" echo "" echo "【string=$string】" print_tips read -p "Please input your choice (1|2|3|4|q|Q):" choice case $choice in 1)len_of_string;; 2)del_hadoop;; 3)rep_first_hadoop_mapreduce;; 4)rep_all_hadoop_mapreduce;; q|Q)exit;; *)echo "Error input,only in (1|2|3|4|q|Q)";; esac done
命令替換
Shell 命令替換是指將命令的輸出結(jié)果賦值給某個變量。比如,在某個目錄中輸入 ls 命令可查看當(dāng)前目錄中所有的文件,但如何將輸出內(nèi)容存入某個變量中呢?這就需要使用命令替換了,這也是 Shell 編程中使用非常頻繁的功能。
語法 | |
方法一 | `command` |
方法二 | $(command) |
示例
# 獲取系統(tǒng)的所有用戶并輸出 #!/bin/bash index=1 for user in `cat /etc/passwd | cut -d ":" -f 1` do echo "這是第 $index 個用戶,名稱為:$user" index=$(($index + 1)) # $(())主要用來進(jìn)行整數(shù)運(yùn)算,引用變量前面可以加$也可以不加 done # 根據(jù)系統(tǒng)時間計算今年或明年 #!/bin/bash year=`date +%Y` echo "今年是$year年,明年是$(($year+1))年" # 根據(jù)系統(tǒng)時間獲取今年還剩下多少星期,已經(jīng)過了多少星期 #!/bin/bash # 計算現(xiàn)在是今年第幾天 #!/bin/bash days=$(date +%j) weeks=$((days/7)) remain_weeks=$((52-weeks)) echo "今年還剩$remain_weeks個星期,已經(jīng)過了$weeks個星期" # 判定nginx進(jìn)程是否存在,若不存在則自動拉起進(jìn)程 #!/bin/bash nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l) if [ $nginx_process_num -eq 0 ];then echo "nginx未啟動,拉起中..." systemctl start nginx else echo "nginx已啟動..." fi
有類型變量
在之前的變量聲明中都是沒有指定變量類型的,在Shell編程中如果需要為變量指定類型則需要使用declare和typeset命令。這兩個命令是等價的。(下表中-號為添加,取消則使用+號,如+x)
參數(shù) | 含義 |
-r | 將變量設(shè)置為只讀 |
-i | 將變量設(shè)置為整數(shù) |
-a | 將變量定義為數(shù)組 |
-f | 顯示此腳本前定義過的所有函數(shù)及內(nèi)容 |
-F | 僅顯示此腳本前定義過的函數(shù)名 |
-x | 將變量聲明為環(huán)境變量 |
示例
# 設(shè)置為只讀 var1="hello wordl" var1="hello shell" declare -r var1 var1="hello java" ->-bash: var1: readonly variable # 設(shè)置為整形 num1=20 num2=$num1+30 echo $num2 ->20+30 #linux默認(rèn)設(shè)置為字符串 declare -i num3 num3=$num1+30 echo $num3 ->50 # 定義數(shù)組 declare -a array array=(1 2 3 4) # 輸出全部內(nèi)容 echo ${array[@]} # 輸出下標(biāo)索引為1的內(nèi)容 echo ${array[1]} # 數(shù)組內(nèi)元素個數(shù) echo ${#array[@]} # 指定索引賦值 array[0]=555 # 尾部添加元素 array[4]=666 # 刪除元素 # 刪除索引為2的元素 unset array[2] # 清空整個數(shù)組 unset array # 分片訪問 # 顯示數(shù)組下標(biāo)索引從1開始到3的三個元素(包頭不包尾) ${array[@]:1:4} # 數(shù)組遍歷 for n in ${array[@]} do echo $n done # 顯示腳本前定義過的所有函數(shù)及內(nèi)容 # 在前問小試牛刀的print_tips方法后添加declare -f,即可發(fā)現(xiàn)只顯示了命令前的函數(shù)及內(nèi)容
數(shù)學(xué)運(yùn)算之expr
expr操作符對照表:
操作符 | 含義 |
num1 | num2 | num1不為空且非0,返回num1;否則返回num2 |
num1 & num2 | num1不為空且非0,返回num1;否則返回0 |
num1 < num2 | num1小于num2,返回1;否則返回0 |
num1 <= num2 | num1小于等于num2,返回1;否則返回0 |
num1 = num2 | num1等于num2,返回1;否則返回0 |
num1 != num2 | num1不等于num2,返回1;否則返回0 |
num1 > num2 | num1大于num2,返回1;否則返回0 |
num1 >= num2 | num1大于等于num2,返回1;否則返回0 |
注意:如果需要在命令行中使用這些運(yùn)算需要轉(zhuǎn)義,如expr $num1 \| $num2,expr $num1 \> $num2,否則報錯。
num1=20 num2=100 expr $num1 \| $num2 expr $num1 \& $num2 expr $num1 \< $num2 expr $num1 \<= $num2 expr $num1 \> $num2 expr $num1 \>= $num2 expr $num1 = $num2 expr $num1 != $num2 expr $num1 + $num2 expr $num1 - $num2 expr $num1 \* $num2 expr $num1 / $num2 expr $num1 % $num2
數(shù)學(xué)運(yùn)算之bc
bc是bash內(nèi)建的運(yùn)算器,支持浮點(diǎn)數(shù)運(yùn)算。默認(rèn)情況下bc運(yùn)算精確到整數(shù),可以設(shè)置scale來保留指定位數(shù)的小數(shù)。
bc bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. This is free software with ABSOLUTELY NO WARRANTY. For details type `warranty'. 23/5 4 scale=2 23/5 4.60
在shell中通常通過管道來使用bc。如:echo "2.5/3.65" | bc或echo 'scale=2; (2.777 - 1.4744)/1' | bc。注意:后者的/1操作,如果不進(jìn)行除法則無法保留指定位數(shù)的小數(shù)
bc 除了 scale 來設(shè)定小數(shù)位之外,還有 ibase(輸入數(shù)據(jù)的進(jìn)制) 和 obase(輸出的數(shù)據(jù)進(jìn)制) 來其它進(jìn)制的運(yùn)算。
echo "ibase=2;111" |bc ->7 echo "obase=2;192" |bc ->11000000
到此這篇關(guān)于Shell編程之變量的高級用法詳解的文章就介紹到這了,更多相關(guān)Shell 變量的高級用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
linux shell腳本學(xué)習(xí)xargs命令使用詳解
xargs是一條Unix和類Unix操作系統(tǒng)的常用命令。它的作用是將參數(shù)列表轉(zhuǎn)換成小塊分段傳遞給其他命令,以避免參數(shù)列表過長的問題2013-12-12Linux系統(tǒng)診斷之內(nèi)存基礎(chǔ)深入詳解
這篇文章主要介紹了Linux系統(tǒng)診斷之內(nèi)存基礎(chǔ)深入詳解,雖然是基礎(chǔ)但是列舉的很詳細(xì),有感興趣的同學(xué)可以研究下2021-03-03