網中人“shell十三問之變數替換” 外傳(初學shell必看)(轉)
網中人“shell十三問之變數替換” 外傳(初學shell必看)(轉)[@more@]初看第八問,不解。想:其它初學shell者亦同。故解之!
變數替換:
一:簡單賦值和替換
a=bcd
$ echo $a
bcd
$ echo ${a}
bcd
二:變數擴充
除了shell中的meta,其它的[^a-zA-Z0-9_]幾乎都可以作單詞邊界。
同sed中關於單詞邊界[^a-zA-Z0-9_]的描述。
這些功能有時候會在程式中有意想不到的作用!
例如:
$ a=bcd
$ echo ${a}.b
bcd.b
$ echo $a.php
bcd.php
$ echo $a%b
bcd%b
$ echo /$a/bc
/bcd/bc
對於shell中的meta字元,則backslash。
$ echo $a*b
bcd*b
三:變數中的變數
$ a=bcd
$ b=efg
$ c=$a$b
$ echo $c
bcdefg
$ d=$c.ghi
$ echo $d
bcdefg.ghi
思考:若變數互相巢狀,會怎樣呢?
四:變數的特異功能
到網中人的啦!(ps:重寫真是沒激情啊)
file=/dir1/dir2/dir3/my.file.txt
我們可以用 ${ } 分別替換獲得不同的值:
${file#*/}:從變數file的字串左邊開始,刪除字元直到第一個“/”:dir1/dir2/dir3/my.file.txt
${file##*/}:從變數file的字串左邊開始,刪除字元直到最後一個“/”:my.file.txt
${file#*.}:從變數file的字串左邊開始,刪除字元直到第一個“.”:file.txt
${file##*.}:從變數file的字串左邊開始,刪除字元直到最後一個“.”:txt
其實,在“#”後面,無非就是一個匹配問題,不限於兩個,你可以放任意個字元,還可以用shell中另外的萬用字元“?”“[…]”“[!…]”,例如:
$ echo ${file#????}
1/dir2/dir3/my.file.txt
$ echo ${file#*[0-9]}
/dir2/dir3/my.file.txt
$ echo ${file#/dir1/dir[0-9]}
/dir3/my.file.txt
“#”:相當於最小匹配,遇到一個最小的符合其後表示式的字串(單個或多個)即中止匹配動作;
“##”:相當於最大匹配,它儘可能的匹配更多的字元。
我們可以拿“*”來說明:
* 在shell中表示匹配任何符號包括空。當它在只有一個 # 的變數替換中,受最小匹配的影響,它不會匹配任何可列印字元,只匹配一個空,也就是什麼也不匹配,你完全可以忽略它的存在;
當在有兩個 ## 的變數替換中,受最大匹配的影響,一個 * 表示匹配整個字串。
如果想匹配字元“*”時,要在“*”前加一個“”,其後的“*”失去萬用字元的功能。
但是還有一種例外情況(請接著看)
例:
$ file2=abcd.efgh.ijkl.oopp
$ echo ${file2#*.*.*.*}
$ echo ${file2##*.*.*.*}
想想上面兩個的輸出是什麼?
$ echo ${file2#*.*.*.*}
oopp
$ echo ${file2##*.*.*.*}
空
??知道為什麼嗎?因為:“*”匹配任何符號包括空。遇到一個“#”時,最後一個“*”就匹配“空”去了。看下面的:
$ echo ${file2#*.*.*.?}
opp
$ echo ${file2#*.*.*.?*}
opp
$ echo ${file2##*.*.*.?}
opp
$ echo ${file2##*.*.*.?*}
空
do you know?
$ echo $file3
*ab*de*cd
看看下面將輸出什麼?
$ echo ${file3#*ab}
*de*cd
$ echo ${file3#**}
*ab*de*cd
$ echo ${file3##**}
空
$ echo ${file3#*ab}
*de*cd
$ echo ${file3#**}
ab*de*cd
$ echo ${file3##**}
空
$ echo ${file3#*a}
b*de*cd
$ echo ${file3#*a}
b*de*cd
不知各位有沒有發現,“*”在一個“#”中時,並不一定代表“空”,它可能代表一個字元“*”也可能代表其他的什麼字元,如上例的:
“$ echo ${file3#*a}”輸出為“b*de*cd”,其實這還是符合最小匹配理論的。這個表示式的意思是:從變數file3的字串左邊開始刪除字元,直到遇到第一個字元“a”。所以不要和“$ echo ${file3#*a}”混淆,雖然兩個結果是一樣,但意思是不一樣的。
再舉幾個例子,相信大家更容易理解這段話:
$ echo $file3
*ab*de*cd*ab*de //注意:出現兩個“*ab”
$ echo ${file3#*a}
b*de*cd*ab*de //刪除字元,直到出現第一個“a”,“*”為萬用字元
$ echo ${file3##*a}
b*de //刪除字元,直到出現第二個“a”,“*”為萬用字元
$ echo ${file3##*a}
b*de*cd*ab*de //刪除字串“*a”,“*”在“”表示字元“*”
除了萬用字元“*”比較難理解一點,其他的shell萬用字元就都很容易了。
至於“%”,和“#”不同的地方,就是從變數字串右部開始。
${file%/*}:從右部開始拿掉字元,直到遇到(從右部數起的)第一個“/” :/dir1/dir2/dir3
${file%%/*}:從右部開始拿掉字元,直到遇到(從右部數起的)最後一個“/”:(空值)
${file%.*}:從右部開始拿掉字元,直到遇到(從右部數起的)第一個“.”:/dir1/dir2/dir3/my.file
${file%%.*}:從右部開始拿掉字元,直到遇到(從右部數起的)最後一個“.”:/dir1/dir2/dir3/my
變數替換:
一:簡單賦值和替換
a=bcd
$ echo $a
bcd
$ echo ${a}
bcd
二:變數擴充
除了shell中的meta,其它的[^a-zA-Z0-9_]幾乎都可以作單詞邊界。
同sed中關於單詞邊界[^a-zA-Z0-9_]的描述。
這些功能有時候會在程式中有意想不到的作用!
例如:
$ a=bcd
$ echo ${a}.b
bcd.b
$ echo $a.php
bcd.php
$ echo $a%b
bcd%b
$ echo /$a/bc
/bcd/bc
對於shell中的meta字元,則backslash。
$ echo $a*b
bcd*b
三:變數中的變數
$ a=bcd
$ b=efg
$ c=$a$b
$ echo $c
bcdefg
$ d=$c.ghi
$ echo $d
bcdefg.ghi
思考:若變數互相巢狀,會怎樣呢?
四:變數的特異功能
到網中人的啦!(ps:重寫真是沒激情啊)
file=/dir1/dir2/dir3/my.file.txt
我們可以用 ${ } 分別替換獲得不同的值:
${file#*/}:從變數file的字串左邊開始,刪除字元直到第一個“/”:dir1/dir2/dir3/my.file.txt
${file##*/}:從變數file的字串左邊開始,刪除字元直到最後一個“/”:my.file.txt
${file#*.}:從變數file的字串左邊開始,刪除字元直到第一個“.”:file.txt
${file##*.}:從變數file的字串左邊開始,刪除字元直到最後一個“.”:txt
其實,在“#”後面,無非就是一個匹配問題,不限於兩個,你可以放任意個字元,還可以用shell中另外的萬用字元“?”“[…]”“[!…]”,例如:
$ echo ${file#????}
1/dir2/dir3/my.file.txt
$ echo ${file#*[0-9]}
/dir2/dir3/my.file.txt
$ echo ${file#/dir1/dir[0-9]}
/dir3/my.file.txt
“#”:相當於最小匹配,遇到一個最小的符合其後表示式的字串(單個或多個)即中止匹配動作;
“##”:相當於最大匹配,它儘可能的匹配更多的字元。
我們可以拿“*”來說明:
* 在shell中表示匹配任何符號包括空。當它在只有一個 # 的變數替換中,受最小匹配的影響,它不會匹配任何可列印字元,只匹配一個空,也就是什麼也不匹配,你完全可以忽略它的存在;
當在有兩個 ## 的變數替換中,受最大匹配的影響,一個 * 表示匹配整個字串。
如果想匹配字元“*”時,要在“*”前加一個“”,其後的“*”失去萬用字元的功能。
但是還有一種例外情況(請接著看)
例:
$ file2=abcd.efgh.ijkl.oopp
$ echo ${file2#*.*.*.*}
$ echo ${file2##*.*.*.*}
想想上面兩個的輸出是什麼?
$ echo ${file2#*.*.*.*}
oopp
$ echo ${file2##*.*.*.*}
空
??知道為什麼嗎?因為:“*”匹配任何符號包括空。遇到一個“#”時,最後一個“*”就匹配“空”去了。看下面的:
$ echo ${file2#*.*.*.?}
opp
$ echo ${file2#*.*.*.?*}
opp
$ echo ${file2##*.*.*.?}
opp
$ echo ${file2##*.*.*.?*}
空
do you know?
$ echo $file3
*ab*de*cd
看看下面將輸出什麼?
$ echo ${file3#*ab}
*de*cd
$ echo ${file3#**}
*ab*de*cd
$ echo ${file3##**}
空
$ echo ${file3#*ab}
*de*cd
$ echo ${file3#**}
ab*de*cd
$ echo ${file3##**}
空
$ echo ${file3#*a}
b*de*cd
$ echo ${file3#*a}
b*de*cd
不知各位有沒有發現,“*”在一個“#”中時,並不一定代表“空”,它可能代表一個字元“*”也可能代表其他的什麼字元,如上例的:
“$ echo ${file3#*a}”輸出為“b*de*cd”,其實這還是符合最小匹配理論的。這個表示式的意思是:從變數file3的字串左邊開始刪除字元,直到遇到第一個字元“a”。所以不要和“$ echo ${file3#*a}”混淆,雖然兩個結果是一樣,但意思是不一樣的。
再舉幾個例子,相信大家更容易理解這段話:
$ echo $file3
*ab*de*cd*ab*de //注意:出現兩個“*ab”
$ echo ${file3#*a}
b*de*cd*ab*de //刪除字元,直到出現第一個“a”,“*”為萬用字元
$ echo ${file3##*a}
b*de //刪除字元,直到出現第二個“a”,“*”為萬用字元
$ echo ${file3##*a}
b*de*cd*ab*de //刪除字串“*a”,“*”在“”表示字元“*”
除了萬用字元“*”比較難理解一點,其他的shell萬用字元就都很容易了。
至於“%”,和“#”不同的地方,就是從變數字串右部開始。
${file%/*}:從右部開始拿掉字元,直到遇到(從右部數起的)第一個“/” :/dir1/dir2/dir3
${file%%/*}:從右部開始拿掉字元,直到遇到(從右部數起的)最後一個“/”:(空值)
${file%.*}:從右部開始拿掉字元,直到遇到(從右部數起的)第一個“.”:/dir1/dir2/dir3/my.file
${file%%.*}:從右部開始拿掉字元,直到遇到(從右部數起的)最後一個“.”:/dir1/dir2/dir3/my
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-947151/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Shell轉義字元與變數替換字元變數
- Linux Shell程式設計(6)——變數替換Linux程式設計變數
- shell替換程式碼
- [Shell] awk初學之常見問題
- Shell 變數學習變數
- Linux之shell變數Linux變數
- Linux/Unix shell sql 之間傳遞變數LinuxSQL變數
- Shell學習【變數使用】變數
- Shell 變數變數
- Shell變數變數
- shell 變數賦值問題變數賦值
- Shell入門——shell特性、變數變數
- Shell學習【引數傳遞】
- Shell 中的命令替換及引數擴充套件套件
- shell替換程式裡的程式碼
- [轉]Shell向Perl指令碼中傳遞變數的方法指令碼變數
- Shell程式設計-shell變數1程式設計變數
- shell基礎篇(二)-shell變數變數
- [Shell] shell中的內部變數變數
- Shell變數的作用域問題變數
- Shell--變數變數
- shell Bash變數變數
- (2) Shell 變數變數
- TCSH shell變數和特徵配置(轉)變數特徵
- Shell階段02 shell變數運算(整數運算/小數運算), shell變數案例變數
- Shell程式設計-02-Shell變數程式設計變數
- linux_shell awk中傳遞變數Linux變數
- [linux shell]引數傳遞之空格Linux
- Linux Shell命令換行問題(轉)Linux
- Linux基礎之Shell與變數Linux變數
- 2.Shell變數變數
- Linux Shell變數Linux變數
- [shell基礎]——變數變數
- awk引用shell變數變數
- awk使用shell變數變數
- Shell程式設計-shell變數2-位置變數和預定義變數程式設計變數
- shell程式設計學習筆記(二):Shell中變數的使用程式設計筆記變數
- grep、sed批量替換檔案內容shell