bash 教程 shell 字符串 转义 [MD]
博文地址
| 我的GitHub | 我的博客 | 我的微信 | 我的郵箱 |
|---|---|---|---|
| baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
目錄
目錄目錄Bash 字符串字符串的表示單引號和雙引號轉義字符 \不可打印字符 \n\r\t\b\a模式擴展字符 ~?*[]{}()$雙引號中的三個特殊字符使用 Here 文檔輸入多行字符串使用 Here 字符串模擬標準輸入提取子字符串替換匹配的字符串字符串頭部的模式匹配字符串尾部的模式匹配任意位置的模式匹配計算字符位置其他簡單操作
Bash 字符串
bash-tutorial
Bash 教程
本文改編自 網(wǎng)道的 Bash 教程,主要為了精簡大量本人不感興趣的內(nèi)容。
字符串的表示
單引號和雙引號
shell 中的字符串可以用單引號,也可以用雙引號,也可以不用引號。
單引號中的特殊字符(包括反斜杠)都會變?yōu)槠胀ㄗ址?code>雙引號里面的大部分特殊字符會變成普通字符(除了后面提到的三個特殊字符)。
echo 白 "白" '白' # 【白 白 白】字符串可以使用雙引號、單引號包裹,也可以省略引號
# 引號嵌套
echo '單中有"雙' # 【單中有"雙】,單引號中的雙引號不需要轉義---單引號中的特殊字符都會變?yōu)槠胀ㄗ址?echo "雙中有'單" # 【雙中有'單】,雙引號中的單引號不需要轉義
echo 需\"要\'轉義 # 【需"要'轉義】,沒有引號時,雙引號、單引號都需要轉義
echo "需要\"轉義" # 【需要"轉義】,雙引號中的雙引號需要轉義
echo "不"需要"轉義" # 【不需要轉義】,雙引號中可成對出現(xiàn)一對雙引號,作為字符串拼接使用(其實可認為是兩個字符串)
# 單引號中的單引號
echo it's # 【(等待輸入)】,不正確,等待輸入配對的單引號
echo 'it\'s' # 【(等待輸入)】,單引號中的特殊字符都會變?yōu)槠胀ㄗ址詥我栔胁荒苁褂梅葱备苻D義
echo $'it\'s' # 【it's】,正確,不建議
echo 'it''s' # 【its】,正確,單引號中可成對出現(xiàn)一對單引號,作為字符串拼接使用(其實可認為是兩個字符串)
轉義字符 \
echo '\' # 【\】,單引號中的特殊字符都會變?yōu)槠胀ㄗ址ǚ葱备?echo \ # 【(等待輸入)】,按回車后,命令行不會立即執(zhí)行,而是等待用戶繼續(xù)輸入,直到下個回車后才會一并執(zhí)行
echo \\ # 【\】,連續(xù)使用兩個反斜線,可對反斜線自身轉義
echo "\\" # 【\】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo "\" # 【"】,轉義后,由于缺少配對的【"】,所以會等待用戶輸入匹配的【"】后才會執(zhí)行
不可打印字符 \n\r\t\b\a
【\a】響鈴、【\b】退格、【\n】換行、【\r】回車、【\t】制表
echo "a\a\b\n\r\tb" # 【a\a\b\n\r\tb】,默認情況下,雙引號和單引號會讓不可打印字符變成普通字符
echo -e "a\tb" # 【a b】,放在雙引號和單引號里面,并使用【-e】參數(shù),會解釋里面的不可打印字符
echo a\b\tc\\td # 【abtc\td】,不加雙引號和單引號時,單獨的反斜杠會被忽略,不可打印字符會變成普通字符
echo -e a\b\tc\\td # 【abtc d】,加參數(shù)【-e】時,單獨的反斜杠會被忽略,但不可打印字符也會被解釋
echo a\ # 【(等待輸入)】,按回車后,命令行不會立即執(zhí)行,而是等待用戶繼續(xù)輸入,直到下個回車后才會一并執(zhí)行
echo "a\ # 【(等待輸入)】,同上,等待用戶繼續(xù)輸入,直到下個【"+回車】后才會一并執(zhí)行
echo 'a\ # 【(等待輸入)】,同上,注意,行尾的【\】不會被替換為換行或空格,而是會直接合并兩行的內(nèi)容
pwd;\ # 【(等待輸入)】,行尾的反斜杠可以使換行符 \n 變成普通字符,從而可以將一行命令寫成多行
ll
模式擴展字符 ~?*[]{}()$
a=白
echo $a "$a" # 【白 白】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo \$a "\$a" # 【$a $a】,在特殊字符前面加上反斜杠進行轉義(escape)后,可以變?yōu)槠胀ㄗ址?echo '$a \$a' # 【$a \$a】,單引號中的特殊字符都會變?yōu)槠胀ㄗ址?echo \~ \? \* # 【~ ? *】,不加反斜杠進行轉義時,模式擴展字符會自動擴展(擴展失敗時,會變?yōu)槠胀ㄗ址?
雙引號中的三個特殊字符
單引號中的特殊字符(包括反斜杠)都會變?yōu)槠胀ㄗ址p引號里面的大部分特殊字符會變成普通字符,但是以下三個特殊字符除外:
美元符號 $:用來引用變量
反斜杠 \:用來轉義
反引號 `:執(zhí)行子命令
echo `pwd` # 【/home/bqt】,使用反引號可以顯示命令執(zhí)行的結果
echo "`pwd`" # 【/home/bqt】,雙引號里面的大部分特殊字符會變成普通字符,除了【$】【\】【`】
echo "hello # 換行符在雙引號之中不再被解釋為命令的結束,所以可以利用雙引號在命令行輸入多行文本
ls "b qt.txt" # 文件名包含空格時,必須將文件名放在雙引號或單引號里面
echo "a b" # 雙引號會原樣保存多余的空格
echo "$(cal)" # 雙引號會保存命令原始的輸出格式,不加雙引號時會單行輸出
使用 Here 文檔輸入多行字符串
Here 文檔(here document)是一種輸入多行字符串的方法,格式如下:
command << token # 開始標記,由兩個小于號 + Here 文檔的名稱組成,名稱可以隨意取
text # 字符串的內(nèi)容
token # 結束標記,單獨一行頂格寫的 Here 文檔名稱
Here 文檔的本質(zhì)是重定向,它將字符串重定向輸出給某個命令,相當于 echo text | command
Here 字符串只適合那些可以接受標準輸入作為參數(shù)的命令,對于 echo 等其他命令無效
Here 文檔不能作為變量的值,只能用于命令的參數(shù)
Here 文檔內(nèi)部會發(fā)生變量替換,并且雙引號和單引號都變成了普通字符
Here 文檔內(nèi)部支持反斜杠轉義,但是不支持通配符擴展
a=白
cat << bqt # Here 文檔內(nèi)部會發(fā)生變量替換,并且雙引號和單引號都變成了普通字符
$a "$a" '$a' # 【白 "白" '白'】
bqt
cat << 'bqt' # 把 Here 文檔的開始標記放在單引號之中,可以避免變量替換
$a "$a" '$a' # 【$a "$a" '$a'】
bqt
使用 Here 字符串模擬標準輸入
Here 文檔還有一個變體,叫做 Here 字符串(Here string),使用三個小于號(<<<)表示。它的作用是將字符串通過標準輸入,傳遞給命令。
cat <<< 'aaa' # 等同于【echo 'aaa' | cat】
有些命令直接接受給定的參數(shù),與通過標準輸入接受參數(shù),結果是不一樣的。例如cat命令,只能接受標準輸入作為參數(shù),如果直接將字符串放在命令后面,會被當作文件名,即cat aaa里面的aaa會被解釋成文件名。這時就可以用 Here 字符串,將字符串aaa通過標準輸入傳給cat命令。
提取子字符串
${varname:offset}:從第 offset 個字符開始(從0開始計算),截取到字符串的結尾
${varname:offset:length}:從第 offset 個字符開始(從0開始計算),截取 length 個字符
${varname:offset:-length}:從第 offset 個字符開始(從0開始計算),排除末尾的 length 個字符
${varname: -offset}:從倒數(shù)第 offset 個字符開始(從1開始計算),截取到字符串的結尾
${varname: -offset:length}:從倒數(shù)第 offset 個字符開始(從1開始計算),截取 length 個字符
${varname: -offset:-length}:從倒數(shù)第 offset 個字符開始(從1開始計算),排除末尾的 length 個字符
注意事項:
不能直接操作字符串,只能通過變量名來讀取字符串
不會改變原始字符串
負的 -offset 前面必須有一個空格, 以防與 ${variable:-word} 的設置變量默認值語法混淆
bqt="baiqiantao"
echo ${#bqt} # 【10】,字符串的長度
echo ${bqt:3} # 【qiantao】,從第 3 個字符開始(從 0 開始計算),截取到字符串的結尾
echo ${bqt:3:4} # 【qian】,從第 3 個字符開始(從 0 開始計算),截取 4 個字符
echo ${bqt:3:-1} # 【qianta】,從第 3 個字符開始(從 0 開始計算),排除末尾的 1 個字符
echo ${bqt: -3} # 【tao】,從倒數(shù)第 3 個字符開始(從 1 開始計算),截取到字符串的結尾
echo ${bqt: -3:2} # 【ta】,從倒數(shù)第 3 個字符開始(從 1 開始計算),截取 2 個字符
echo ${bqt: -3:-1} # 【ta】,從倒數(shù)第 3 個字符開始(從 1 開始計算),排除末尾的 1 個字符
# 越界情況
echo ${bqt:11:-1} # 【空字符串】,如果 offset 越界了,那么直接返回空字符串,后面的 length 無效
echo ${bqt:10:-1} # 【報錯】,如果 offset 沒有越界,那么排除的長度 length 不能超過子字符串的長度
echo ${bqt: -3:-4} # 【報錯】,如果 offset 沒有越界,那么排除的長度 length 不能超過子字符串的長度
echo ${bqt:3:40}-${bqt: -3:40} # 【qiantao-tao】,如果 offset 沒有越界,那么截取的長度沒有大小限制
# 以下全部返回空字符串
echo ${bqt:30}-${bqt:30:4}-${bqt:30:-4}-${bqt:30:40}-${bqt:30:-40}
echo ${bqt: -30}-${bqt: -30:4}-${bqt: -30:-4}-${bqt: -30:40}-${bqt: -30:-40}
替換匹配的字符串
如果模式匹配成功,就刪除匹配的部分,返回剩下的部分(原始變量不會發(fā)生變化)。如果匹配不成功,則返回原始字符串。
字符串頭部的模式匹配
檢查 pattern 是否匹配變量 var 的開頭
${var#pattern}:如果匹配,則刪除最短匹配(又稱非貪婪匹配)的部分,返回剩余部分
${var##pattern}:如果匹配,則刪除最長匹配(又稱貪婪匹配)的部分,返回剩余部分
${var/#pattern/string}:如果匹配,則將匹配的部分替換成 string(可為空) 后返回
path=/home/bqt/test/hello
echo ${path#/*/} # 【bqt/test/hello】,匹配模式【/*/】的最短匹配是【/home/】
echo ${path##/*/} # 【hello】,匹配模式【/*/】的最長匹配是【/home/bqt/test/】
echo ${path#*/} # 【home/bqt/test/hello】,匹配模式【*/】的最短匹配是【/】
echo ${path##*/} # 【hello】,匹配模式【*/】的最長匹配是【/home/bqt/test/】,此模式可用來返回文件名
foo=home/bqt/test/hello
echo ${foo/#home/xxx} # 【xxx/bqt/test/hello】,將【home】替換為【xxx】
echo ${foo/#home*test/xxx} # 【xxx/hello】,將【home/bqt/test】替換為【xxx】
echo ${foo/#home*test//xxx} # 【/xxx/hello】,將【home/bqt/test】替換為【/xxx】
echo ${foo/#home*test\//xxx} # 【xxxhello】,將【home/bqt/test/】替換為【xxx】
echo ${foo/##*/xxx} # 【home/bqt/test/hello】,不支持【##】,匹配模式會識別為【#*】
字符串尾部的模式匹配
檢查 pattern 是否匹配變量 var 的尾部
${var%pattern}:如果匹配,則刪除最短匹配(又稱非貪婪匹配)的部分,返回剩余部分
${var%%pattern}:如果匹配,則刪除最長匹配(又稱貪婪匹配)的部分,返回剩余部分
${var/%pattern/string}:如果匹配,則將匹配的部分替換成 string(可為空) 后返回
path=/home/bqt/test/hello
echo ${path%t*} # 【/home/bqt/tes】
echo ${path%%t*} # 【/home/bq】
echo ${path%/*} # 【/home/bqt/test】,此模式可刪除路徑的文件名部分,只留下目錄部分
echo ${path/%hello/xxx} # 【/home/bqt/test/xxx】,將【hello】替換為【xxx】
echo ${path/%b*hello/xxx} # 【/home/xxx】,將【bqt/test/hello】替換為【xxx】
echo ${path/%t/*hello/xxx} # 【/home/bqt/test/hello】,因為不匹配結尾,所以返回原始字符串
echo ${path/%t\/*hello/xxx} # 【/home/bqxxx】,將【t/test/hello】替換為【xxx】,貪婪匹配
echo ${path/%%*/xxx} # 【home/bqt/test/hello】,不支持【%%】,匹配模式會識別為【%*】
任意位置的模式匹配
檢查 pattern 是否匹配變量 var 的一部分
${var/pattern/string}:如果匹配,則將最長匹配的那部分替換成 string 后返回,僅替換第一個匹配
${var//pattern/string}:如果匹配,則將最長匹配的那部分替換成 string 后返回,所有匹配都替換
如果省略了 string 部分,相當于匹配的部分替換成空字符串,即刪除匹配的部分
path=home/bqt/test/hello
echo ${path/??t/xxx} # 【home/xxx/test/hello】僅替換第一個匹配
echo ${path//??t/xxx} # 【home/xxx/txxx/hello】所有匹配都替換
echo ${path/\/*t/xxx} # 【homexxx/hello】最長匹配
echo ${path//\/*t/xxx} # 【homexxx/hello】最長匹配
echo ${path//??t/} # 【home//t/hello】刪除所有匹配的部分
echo -e ${PATH//:/"\n"} # 將環(huán)境變量 PATH 中的所有分隔符,由【:】替換成【\n】,并解釋為換行符
計算字符位置
expr index "$var" sub:返回字符串 sub 中的所有字符,在變量 var 中的最小位置
bqt="baiqiantao"
echo `expr index "$bqt" a` #【2】,返回字符 a 在變量中的最小位置
echo `expr index "$bqt" qa` #【2】,返回字符 q 或 a 在變量中的最小位置
echo `expr index "$bqt" xy` #【0】,如果所有字符都不存在,則返回 0
echo `expr index "$bqt" xq` #【4】,忽略不存在的字符 x,返回字符 q 在變量中的最小位置
其他簡單操作
${#varname}:字符串的長度
${varname^^}:轉為大寫
${varname,,}:轉為小寫
bqt="baiQianTao"
echo ${#bqt} # 【10】,字符串的長度
echo $#bqt # 【0bqt】,大括號是必需的,否則會將 $# 理解成腳本的參數(shù)個數(shù),將變量名理解成文本
echo ${bqt^^} # 【BAIQIANTAO】,轉為大寫
echo ${bqt,,} # 【baiqiantao】,轉為小寫
2021-12-19
本文來自博客園,作者:白乾濤,轉載請注明原文鏈接:https://www.cnblogs.com/baiqiantao/p/15708280.html
總結
以上是生活随笔為你收集整理的bash 教程 shell 字符串 转义 [MD]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小兔伴伴家庭动物园AR智能早教产品上市
- 下一篇: Linux文件权限读法