Bash 神奇的字串處理 - Shell Parameter Expansion
Posted on Sep 1, 2020 in Unix-like 命令列教學 by Amo Chen ‐ 3 min read
開發時難免都會需要撰寫 shell script 將一些瑣碎的事情自動化,最常見的大概就是利用 bash 撰寫 shell script 。
不過 bash 有些功能並非為眾人皆知卻十分方便,例如 shell parameter expansion 就有許多好用的功能,例如算字串長度、字串取代、大小寫轉換等等,如果學會運用,可以事半功倍!
本篇將介紹幾種好用的 shell parameter expansion 。
本文環境
- Bash 5.0
- macOS 10.15
前言
在 bash 中, ${parameter}
的寫法是 parameter expansion 的基本形式,代表取得 parameter 的值,例如以下 bash script 即是透過 ${VAR}
的方式取得 VAR 的值,所以可以印出 HelloWorld :
#!/bin/bash
VAR="HelloWorld"
echo ${VAR}
p.s. ${VAR}
其實可以省略為 $VAR
,也就是我們很常見的 bash script 變數用法。
除了透過基本形式取得變數值的部分, parameter expansion 還提供在 parameter 前方或後方加上一些特殊符號,例如 #
/
@
…. 等等以擴充其用途,例如取得字串長度,字串取代、對變數進行賦值等等。
字串長度
首先看利用 shell parameter expansion 取得字串長度的方法。
十分簡單,只要在 parameter
的前方加上 #
即可,例如以下範例:
$ string=abcdefghi
$ echo ${#string}
9
字串切片
bash 的 shell parameter expansion 也有類似 Python slice 切片的功能,例如 ${string:2}
取得字串第 2 個字元之後的所有字元,以及 ${string:2}
取的字串第 2 個字元之後 1 個字元:
$ string=abcdefghi
$ echo ${string:2}
cdefghj
$ echo ${string:2:1}
c
字串刪除
bash 的 parameter expansion 也有提供若干字串刪除的方式,包含刪除字串的前綴(prefix)、字串的後綴(postfix)、刪除符合的字串等。
刪除字串前綴(prefix)
如果想刪除某些字串前面固定格式的字元時,可以在 parameter
後方加上 #
以及欲刪除的前綴(prefix),例如以下範例想刪除字串開頭的 abc (如果 parameter 不是 abc 開頭則不會進行任何動作喔):
$ string=abcdefghi
$ echo ${string#abc}
defghi
刪除後綴(postfix)字串
如果想刪除某些字串後面固定格式的字元時,則可以在 parameter
後方加上 %
以及欲刪除的後綴(prefix),例如以下範例想刪除字串結尾的 ghi (如果 parameter 不是 ghi 結尾則不會進行任何動作喔):
$ string=abcdefghi
$ echo ${string%ghi}
abcdef
刪除符合的字串
如果沒辦法知道想刪除的字串會在哪個位置出現,則可以在 parameter
後方使用 /
加上欲刪除的字串,例如以下範例刪除字串中間的 def :
$ string=abcdefghi
$ echo ${string/def}
abcghi
取代字串
取代字串的方式與刪除類似,額外加上 /取代字串
即可,例如以下範例將 def 取代為 3 個米字號:
$ string=abcdefghi
$ echo ${string/def/***}
abc***ghi
如果取代的字串出現多次,上述的寫法僅會取代 1 次,例如:
$ string=abcabcabc
$ echo ${string/abc/***}
***abcabc
如果要取代多次出現的字串,可以將 /
改為 //
例如以下 //abc/***
的部分:
$ string=abcabcabc
$ echo ${string//abc/***}
*********
字串轉換大小寫
bash 的 parameter expansion 也提供大小寫轉換的功能,而且也十分好記:
^
代表第 1 個字元轉大寫^^
代表全部轉大寫,
代表第 1 個字元轉小寫,,
代表全部轉小寫
詳見以下範例:
字串轉大寫
$ string=abcdefghi
$ echo ${string^}
Abcdefghi
$ echo ${string^^}
ABCDEFGHI
字串轉小寫
$ string=ABCDEFGHI
$ echo ${string,}
aBCDEFGHI
$ echo ${string,,}
abcdefghi
取得檔名與副檔名
結合前述提到的各種字串處理的技巧,我們就能更方便地做到一些事,例如經常會用到的取得檔名與副檔名:
$ file=filename.txt
$ echo ${file%.*}
filename
$ echo ${file#*.}
txt
上述 ${file%.*}
中的 %.*
指的是刪除 .
之後(包含 .
)的所有字元。
而 ${file#*.}
中的 #.*
指的則是刪除 .
之前(包含 .
)的所有字元。
結語
Bash 的 shell parameter expansion 文件中,還有許多其他方便的用法,有興趣的話,可以花時間實際閱讀與操作看看,相信能夠收穫不少。
以上, Happy Coding!
References
https://www.linuxjournal.com/content/bash-parameter-expansion
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html