3.shell 基本特性之~ shell展開詳解

第 3 章目錄:

3.1 shell 語法
3.2 shell 命令
3.3 shell 函數(shù)
3.4 shell 參數(shù)
3.5 shell 展開
3.6 重定向
3.7 命令執(zhí)行
3.8 shell 腳本

本文件內(nèi)容為 "3.5 shell 展開"


3.5 小節(jié)目錄:

3.5.1 花括號展開 對花括號中的表達(dá)式的展開
3.5.2 波浪線展開
3.5.3 shell 參數(shù)展開
3.5.4 命令替換 把命令的輸出當(dāng)做參數(shù)使用
3.5.5 算術(shù)展開 如何在 shell 表達(dá)式中進(jìn)行算術(shù)運(yùn)算
3.5.6 過程替換 一種對命令進(jìn)行讀寫的方法
3.5.7 單詞分割 展開結(jié)果是如何分割成獨(dú)立的參數(shù)的
3.5.8 文件名展開
3.5.9 引用刪除

命令行被分割為 token 之后,就開始進(jìn)行展開。一共有 7 種展開:

1,花括號展開
2,波浪線展開
3,參數(shù)和變量展開
4,命令替換
5,算術(shù)展開
6,單詞分割
7,文件名展開

展開的順序是:

1,花括號展開
2,波浪線展開
3,參數(shù),變量,算術(shù)展開和命令替換(在支持過程替換的系統(tǒng)上,過程替換也在這里進(jìn)行)
4,單詞分割
5,文件名展開

只有花括號展開,單詞分割,文件名展開能改變展開結(jié)果的單詞個(gè)數(shù)。

其他展開一般把一個(gè)單詞展開為另一個(gè)單詞,有兩個(gè)例外情況:'"$@"' 和 '"${NAME[@]}"'。

所有展開完成后,進(jìn)行引用刪除

3.5.1 花括號展開


在花括號內(nèi),可以是以逗號分隔的字符串,或者是一個(gè)序列表達(dá)式。在花括號前后,可以跟前綴和后綴。

花括號展開支持嵌套,展開的字符串是無序的,從左到右的順序被保留。

1,逗號分隔

# echo a{d,c,b}e
ade ace abe

前綴 a 和 后綴 e 與展開結(jié)果的每一個(gè)字符串結(jié)合生成最終結(jié)果。

2,序列表達(dá)式

序列表達(dá)式的語法是:
'{X..Y[..INCR]}'

X,Y 是數(shù)字或單個(gè)字符,INCR 是步進(jìn)。

當(dāng) X,Y 是數(shù)字時(shí),展開為 X 到 Y 的所有數(shù)字。數(shù)字可加前綴 0,如 01,001,使展開結(jié)果保持相同的寬度。

當(dāng) X 或 Y 以 0 開頭時(shí),shell 嘗試將生成結(jié)果保持相同寬度。必要時(shí)以 0 進(jìn)行填充。

{01..100} 生成 001, 002, ..., 100

步進(jìn):
{1..10..2} 生成 1 3 5 7 9

當(dāng) X,Y 是字母時(shí),按字典序展開。X,Y 必須是相同類型。當(dāng)給出步進(jìn)時(shí),相鄰字母的距離為步進(jìn)的距離。默認(rèn)步進(jìn)為 1 或 -1(看具體情況)。

{a..g..2} 生成 a c e g

花括號展開在其它展開之前進(jìn)行,任何對于其它展開有特殊意義的字符都被保留。

在進(jìn)行花括號展開時(shí),bash 對于花括號的上下文和括號內(nèi)的文本內(nèi)容不做任何的語法解釋。

為避免與參數(shù)展開產(chǎn)生沖突,字符串 '${' 不被認(rèn)為需要做花括號展開。

要進(jìn)行正確的花括號展開,必須包含未被引用(unquoted)的 '{' 和 '}'。并且在括號中,至少有一個(gè)未被引用的 ',' 或者一個(gè)有效的“序列表達(dá)式”。

書寫不正確的花括號展開保留原樣。

把 '{' 和 ',' 引用起來,可避免被認(rèn)為是花括號展開的一部分。為避免與參數(shù)展開產(chǎn)生沖突,字符串 '${' 不被認(rèn)為需要做花括號展開。

這個(gè)構(gòu)造典型的應(yīng)用場景是,當(dāng)字符串前綴太長的時(shí)候,比如創(chuàng)建多個(gè)包含絕對路徑的文件時(shí),使用花括號展開可以簡化命令行語句,如:

mkdir /usr/local/src/bash/{old,new,dist,bugs}

chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}} # 兩個(gè)子目錄

3.5.2 波浪線展開


如果一個(gè)單詞以未被引用的 '~' 開頭,這個(gè)單詞所有到斜線 '/'(如果有得話) 為止的字符被認(rèn)為是一個(gè) 波浪線前綴字符串(TILDE-PREFIX)。

如果在 “波浪線前綴字符串” 中沒有被引號引用的字符,那么所有波浪線之后的字符組成的字符串被當(dāng)做可能的 LOGIN NAME 對待。

如果 LOGIN NAME 是空字符串,'~' 被替換為 'HOME' 變量的值。
如果 'HOME' 變量沒有設(shè)置,則替換為執(zhí)行 shell 的用戶的家目錄。
否則,'~' 被替換為與 登錄名 關(guān)聯(lián)的家目錄。

$ echo $HOME #HOME 非空
/Users/guli

$ echo ~ #打印當(dāng)前用戶家目錄
/Users/guli

$ echo ~guest #打印guest用戶家目錄
/Users/Guest

$ echo ~root #打印root用戶家目錄
/var/root

如果 波浪線前綴字符串 是 '~+',被替換為 'PWD' 變量的值。

如果是 '~-',被替換為 'OLDPWD' 變量的值(如果存在的話)。

如果 波浪線前綴字符串 是一個(gè)數(shù)字,數(shù)字前跟著一個(gè) '+' 或 '-',如 '~+N',則被替換為 目錄棧 的相應(yīng)順序的元素。等同于 dirs +/-N 的效果。

如果 '+' 或 '-' 沒有給出,默認(rèn)為 '+'。

如果 登錄名 是無效的,或者波浪線展開失敗,則保留原樣。

$ echo ~guset #登錄名 guset 是無效的
~guset

每個(gè)變量賦值會檢查緊跟在 ':' 或第一個(gè) '=' 后面是否有未被引號引用的 '~'。如果有,會進(jìn)行波浪線展開。所以,我們可以通過這種方式賦值給 'PATH','MAILPATH','CDPATH',shell 會用展開后的結(jié)果賦值給變量。

下面是 bash 中的波浪線展開的示例:

'~'
展開為 '$HOME' 的值

'~/foo'
展開為 '$HOME/foo'

'~fred/foo'
展開為 用戶fred的及目錄的子目錄foo: /home/fred/foo

'~+/foo'
展開為 '$PWD/foo'

'~-/foo'
展開為 '{OLDPWD-'~-'}/foo'

'~N'
等同于執(zhí)行 'dirs +N' 的結(jié)果

'~+N'
等同于執(zhí)行 'dirs +N' 的結(jié)果

'~-N'
等同于執(zhí)行 'dirs -N' 的結(jié)果

3.5.3 Shell 參數(shù)展開


'$' 符號引入了三種 shell 展開,包括 “參數(shù)展開”,“命令替換” 和 “算術(shù)表達(dá)式”。

參數(shù)名或參數(shù)符號可以用花括號括起來,使緊跟在參數(shù)名后面的字符與之分隔,這些字符與展開的結(jié)果可共同構(gòu)成最后字符串。如 ${PATH}:/path/to/..

在參數(shù)展開中使用花括號時(shí),'{' 是開始符號,右邊第一個(gè) '}' 是結(jié)束符號。
'}' 不能被轉(zhuǎn)義,或被引號引用,也不能在一個(gè)嵌套的 “算術(shù)表達(dá)式”,或 “命令替換”,或者 “參數(shù)展開”之中。

參數(shù)展開的基本的形式是 ${PARAMETER},整體被替換為 PARAMETER 的值。如果 PARAMETER 是位置參數(shù),而且由兩個(gè)及以上的數(shù)字表示,這時(shí)必須使用花括號:${10}。另外當(dāng) PARAMETER 與其它字符相鄰連接時(shí),也必須使用花括號:${Var}lala。

如果 PARAMETER 的第一個(gè)字符是 "!",會進(jìn)行“間接變量展開”。bash 使用 "!" 之后的部分作為變量名,變量進(jìn)行展開,變量展開結(jié)果作為被引用的對象再進(jìn)行一次展開。"!" 符號必須緊跟在左括號 "{" 后面。但是 ${!PREFIX*} 和 ${!NAME[@]} 是例外,在下面會介紹。

在下面將要介紹的例子中,WORD 可進(jìn)行 “波浪線展開”,“參數(shù)展開”,“命令替換” 以及 “算術(shù)展開”。也就是說,WORD 可以是 $VAR,$(CMD),$(EXPR),~ 形式的。
如果 WORD 是字符串,就不會做展開,在這里不是作為變量名使用的。

當(dāng)不進(jìn)行子字符串展開時(shí),使用下面的形式,bash 會測試 PARAMETER
是否是 unset,或是否是空字符串(null)。
如果刪除冒號 ':',只會測試 PARAMETER 是否是 unset(是否存在)。

'${PARAMETER:-WORD}'

如果 PARAMETER 是 unset 或者 null,最終展開結(jié)果為 WORD 的展開(普通字符串的展開結(jié)果是原字符串保持不變,這里不是取 WORD 的值為最終結(jié)果)。否則,使用 PARAMETER 的變量值為最終結(jié)果。

'${PARAMETER:=WORD}'

如果 PARAMETER 是 unset 或者 null,將 WORD 的展開結(jié)果賦值給PARAMETER(不是 WORD 的參數(shù)值),最終結(jié)果為 PARAMETER 的值。但是“位置參數(shù)”和“特殊參數(shù)”不可通過這種方式賦值。

'${PARAMETER:?WORD}'

如果 PARAMETER 是 unset 或者 null,將 WORD 的展開結(jié)果(如果未給出 WORD,會有一條消息)寫入標(biāo)準(zhǔn)錯(cuò)誤輸出以及 shell,如果 shell 是非交互式的,就退出 shell。否則,使用 PARAMETER 的變量值最終結(jié)果。

'${PARAMETER:+WORD}'

如果 PARAMETER 是 unset 或者 null,結(jié)果是 nothing。否則 WORD 的展開結(jié)果為最終結(jié)果。

'${PARAMETER:OFFSET}'
'${PARAMETER:OFFSET:LENGTH}'

1,當(dāng) PARAMETER 是普通變量時(shí),以字符為單位對參數(shù)值做截取。

OFFSET: 從0開始的位移,截取從位移處開始。
LENGTH: 截取的字符個(gè)數(shù)。如果沒有寫明 LENGTH,即截取從位移處到最后一個(gè)
字符。

OFFSET 和 LENGTH 是“算數(shù)表達(dá)式”。這種展開可被稱為“子字符串展開”。

LENGTH 必須大于等于1,當(dāng)OFFSET是負(fù)數(shù)時(shí),表示從參數(shù)值的尾部向前截取。

2,當(dāng) PARAMETER 是位置參數(shù)時(shí),比如'@',表示從OFFSET處開始的LENGTH個(gè)位置參數(shù)。

3,當(dāng) PARAMETER 是以@或*為下標(biāo)的數(shù)組時(shí),表示從'${PARAMETER[OFFSET]}'開始的 LENGTH 個(gè)數(shù)組變量。

OFFSET 如果是負(fù)數(shù),它的計(jì)數(shù)從數(shù)組最大下標(biāo)+1的地方計(jì)算。

-1 是最后一個(gè)元素的索引

“子字符串展開”用到數(shù)組上時(shí)會產(chǎn)生未知的結(jié)果。

注意:負(fù)數(shù)的 offset 必須用空格與冒號':'隔開,以免和“:-展開”混淆。

對于字符串,索引從 0 開始。(0-based)

對于位置參數(shù),索引從 1 開始。(1-based)

對于數(shù)組,索引從 0 開始。(0-based)

'${!PREFIX*}'
'${!PREFIX@}'

展開結(jié)果為所有以 PREFIX 為前綴的變量的名字。這些變量名以"IFS"變量的第
一個(gè)字符作為分隔符。

如果用的是@,而且在雙引號中展開,每個(gè)變量名展開為獨(dú)立的單詞。

如果用的是*,而且在雙引號中展開,所有變量名展開為一個(gè)單詞。

#  echo ${!BASH@}
BASH BASHOPTS BASHPID BASH_ALIASES BASH_ARGC BASH_ARGV BASH_CMDS BASH_COMMAND BASH_LINENO BASH_SOURCE BASH_SUBSHELL BASH_VERSINFO BASH_VERSION

# for i in "${!BASH*}"; do echo "haha"; done
haha   <=== 展開為1個(gè)單詞,所以打印一次。


# for i in "${!BASH@}"; do echo "haha"; done
haha  <=== 展開為獨(dú)立個(gè)單詞,所以打印多次。
haha
haha
haha
haha
haha
haha
haha
haha
haha
haha
haha
haha

'${!NAME[@]}'
'${!NAME[*]}'

如果 NAME 是數(shù)組變量,展開為數(shù)組索引(key)的列表。

如果 NAME 不是數(shù)組變量,當(dāng)變量存在時(shí)展開為0。

如果用的是@,而且在雙引號中展開,每個(gè)key展開為獨(dú)立的單詞。

'${#PARAMETER}'

展開為參數(shù)值的長度。

如果參數(shù)是“*”或者“@”,展開為位置參數(shù)的個(gè)數(shù)。

當(dāng)參數(shù)是以@或*為下標(biāo)的數(shù)組,展開為數(shù)組中元素的個(gè)數(shù)。

'${PARAMETER#WORD}'
'${PARAMETER##WORD}'

將 WORD 的展開結(jié)果作為匹配模式(如同文件名展開中的通配符匹配),去匹配參數(shù)值的開始部分,匹配到的部分將被刪除。

使用“#”,表示最短匹配,

使用“##”,表示最長匹配。

如果參數(shù)是“*”或者“@”,對每個(gè)位置參數(shù)做上面的操作,

當(dāng)參數(shù)是以@或*為下標(biāo)的數(shù)組,對每個(gè)數(shù)組變量做如上的操作。

'${PARAMETER%WORD}'
'${PARAMETER%%WORD}'

將 WORD 的展開結(jié)果作為匹配模式(如同文件名展開中的通配符匹配),從參數(shù)值的尾部做匹配,匹配到的部分將被刪除。

使用“#”,表示最短匹配,

使用“##”,表示最長匹配。

如果參數(shù)是“*”或者“@”,對每個(gè)位置參數(shù)做上面的操作,

當(dāng)參數(shù)是以@或*為下標(biāo)的數(shù)組,對每個(gè)數(shù)組變量做如上的操作。最終結(jié)果為所有被處理過的參數(shù)的列表。

'${PARAMETER/PATTERN/STRING}'

這個(gè)可視為上面兩個(gè)展開的增強(qiáng)版。PATTERN 的展開結(jié)果作為匹配模式,對參數(shù)的值做最長匹配,匹配的部分替換為 STRING。

一般只有第一個(gè)被匹配的部分才替換為 STRING,但如果 PATTERN 以 '/' 開頭,則所有匹配的部分都將被替換。

如果 PATTERN 以 '#' 開頭,它必須從參數(shù)值的開始部分進(jìn)行匹配。

如果 PATTERN 以 '%' 開頭,它必須從參數(shù)值的尾部進(jìn)行匹配。

如果 STRING=null,匹配的部分將被刪除,而且 PATTERN 后面的 '/' 被忽略。

如果參數(shù)是“*”或者“@”,對每個(gè)位置參數(shù)做上面的操作,

當(dāng)參數(shù)是以@或*為下標(biāo)的數(shù)組,對每個(gè)數(shù)組變量做如上的操作。最終結(jié)果為所有被處理過的參數(shù)的列表。

'${PARAMETER^PATTERN}'
'${PARAMETER^^PATTERN}'
'${PARAMETER,PATTERN}'
'${PARAMETER,,PATTERN}'

這個(gè)展開用來修改參數(shù)值的字符的大小寫。

PATTERN 的展開結(jié)果作為匹配模式

^ 將匹配的第一個(gè)字母的小寫改為大寫。

, 將匹配的第一個(gè)字母的大寫改為小寫。

^^ 將匹配的所有字母改為大寫

,, 將匹配的所有字母改為小寫

如果沒有給出 PATTERN,則默認(rèn)將 PATTERN 設(shè)為 ?,表示匹配任意一個(gè)字符。

如果參數(shù)是“*”或者“@”,對每個(gè)位置參數(shù)做上面的操作,

當(dāng)參數(shù)是以@或*為下標(biāo)的數(shù)組,對每個(gè)數(shù)組變量做如上的操作。最終結(jié)果為所有被處理過的參數(shù)的列表。

3.5.4 命令替換


命令替換允許使用命令的輸出替換命令本身。

命令替換有兩種寫法:

$(COMMAND) 或者 `COMMAND`

命令替換按如下方式進(jìn)行:

1,執(zhí)行命令,使用命令的標(biāo)準(zhǔn)輸出替換上述的命令替換表達(dá)式。
2,如果命令輸出的尾部有跟著換行符,就將換行符刪除。
3,嵌入在命令輸出之中的換行符這時(shí)不會刪除,但可能在進(jìn)行單詞分割的時(shí)候被刪除。

'$(cat FILE)' 與 '$(< FILE)' 是相同的,但后者執(zhí)行速度更快。

使用舊式的反引號 '`' 時(shí),反斜線 '' 失去特殊意義,僅當(dāng)反斜線后跟 '$','`','' 時(shí),反斜線對其進(jìn)行轉(zhuǎn)義,否則只是普通字符。

使用 '$(COMMAND)' 時(shí),圓括號內(nèi)的所有字符不做特殊對待。

命令替換可進(jìn)行嵌套,使用 '`' 形式的命令替換時(shí),內(nèi)部的 '`' 要使用反斜線 '' 轉(zhuǎn)義。

當(dāng)命令替換在雙引號 "" 中進(jìn)行時(shí),替換的結(jié)果不再進(jìn)行單詞分割和文件名展開。

3.5.5 算術(shù)展開


算術(shù)展開允許對算術(shù)表達(dá)式進(jìn)行計(jì)算,并使用計(jì)算結(jié)果替換算術(shù)展開的整個(gè)表達(dá)式。

其語法為:

$(( EXPRESSION ))

對于 EXPRESSION 的處理,如同使用了雙引號 '"' 將之引用,大多數(shù)的特殊字符失去特殊意義,規(guī)則參考前面專門的章節(jié)。這里特殊的一點(diǎn)是,EXPRESSION 中的 '"' 不做特殊對待。

EXPRESSION 中的所有 token 可能進(jìn)行:參數(shù)展開,命令替換,引用取消。

算術(shù)展開可進(jìn)行嵌套。

算術(shù)表達(dá)式的計(jì)算規(guī)則參見后面的小節(jié)。

如果 EXPRESSION 是無效的,bash 打印一條消息到錯(cuò)誤輸出,替換不再進(jìn)行。

3.5.6 過程替換


如果系統(tǒng)支持命名管道(named pipes: FIFOs),或者支持命名的打開文件的 '/dev/fd' 方法,過程替換也被支持。

其形式如下:

<(LIST) 或者 >(LIST)

過程 LIST 執(zhí)行時(shí),其輸出或輸入與 FIFO 或者 '/dev/fd' 下的文件相連。相連的文件名被當(dāng)做一個(gè)參數(shù)傳遞給當(dāng)前命令。

使用 '>(LIST)' 時(shí),對文件寫入,相同于給 LIST 提供輸入。

使用 '<(LIST)' 時(shí),LIST的輸出寫入文件,讀取文件,可以獲得 LIST 的輸出。

注意 '<' 或 '>' 與圓括號之間沒有空格,否則整個(gè)構(gòu)造被解釋為重定向。

過程替換可用時(shí),會與 參數(shù)和變量展開,命令替換,算術(shù)展開同步進(jìn)行。

3.5.7 單詞分割


shell 對 參數(shù)展開,命令替換,算術(shù)展開的結(jié)果進(jìn)行掃描。對未被雙引號引用的部分進(jìn)行單詞分割。

shell 把 '$IFS' 中的每一個(gè)字符當(dāng)做分隔符,對其他展開生成的結(jié)果進(jìn)行單詞分割。

如果 'IFS' 沒有設(shè)置,或者其值正好是默認(rèn)值 '<space><tab><newline>',之前進(jìn)行的展開生成的結(jié)果的開始部分和結(jié)束部分,如果是由這三個(gè)字符組成的連續(xù)字符串,將不做處理。在中間的話,會發(fā)揮單詞分隔符的作用。

如果 'IFS' 的值不是默認(rèn)值,只要空白字符在 'IFS' 之中(這時(shí)的空白符可稱為 IFS 空白符),那么由空白字符(space 和 tab)組成的連續(xù)字符串,出現(xiàn)在展開結(jié)果的開始部分和結(jié)束部分時(shí),被忽略不做處理。

任何在 'IFS' 中的非空白符,與毗連的 'IFS' 空白符一起作為分隔符使用。單詞中的 'IFS' 空白符字符串也作為分隔符使用。如果 'IFS' 是空字符串,不進(jìn)行單詞分割。

顯式出現(xiàn)的空字符串("" 或者 '')將被保留。由參數(shù)值為空的參數(shù)展開生成的未被引號引用的隱式空字符串,將被刪除。如果參數(shù)值為空的參數(shù)展開在雙引號 "" 中進(jìn)行,空字符串被保留。

如果之前沒有進(jìn)行任何展開,單詞分割也不會進(jìn)行。

3.5.8 文件名展開


目錄:

3.8.1 模式匹配 shell 如何進(jìn)行模式匹配

完成單詞分割之后,除非設(shè)置了 '-f' 選項(xiàng)(set 命令),bash 依次掃描每個(gè)單詞,尋找 '*', '?' 和 '[',如果出現(xiàn)其中一個(gè),該單詞被認(rèn)為是一個(gè) PATTERN,并替換為一組按字典序排序的匹配的文件名。

如果沒找到匹配的文件名,而且 shell 選項(xiàng) 'nullglob' 是關(guān)閉的,該單詞保留原樣。
如果沒找到匹配的文件名,而且 shell 選項(xiàng) 'nullglob' 是開啟的,該單詞被刪除。
如果沒找到匹配的文件名,而且 shell 選項(xiàng) 'failglob' 是開啟的,打印一條錯(cuò)誤信息,不執(zhí)行命令。
如果 shell 選項(xiàng) 'nocaseglob' 開啟,匹配時(shí)忽略大小寫。

當(dāng)一個(gè) pattern 用作文件名展開時(shí),字符 '.' 位于文件名首部的 或者'.' 跟在 '/' 之后('/.')時(shí),必須進(jìn)行顯式地匹配,除非開啟了 'dotglob' 選項(xiàng)。

匹配文件名時(shí),字符 '/' 必須進(jìn)行顯式地匹配。除此之外,字符 '.' 不被特殊對待。

參見 'shopt' 命令詳細(xì)了解 'nocaseglob','nullglob','failglob' 以及 'dotglob' 選項(xiàng)。

shell 變量 'GLOBIGNORE' 可用于限制文件名的匹配。

如果設(shè)置了這個(gè)變量,每個(gè)匹配的文件名如果同時(shí)匹配 'GLOBIGNORE' 中的 pattern,這個(gè)文件名從匹配結(jié)果列表中刪除。

'GLOBIGNORE' 變量被設(shè)置且非空時(shí),文件名 '.' 和 '..' 總是被忽略。
'GLOBIGNORE' 變量設(shè)置為非空值時(shí),'dotglob' 選項(xiàng)被開啟,所以所有其他以 '.' 開始的文件名也會被匹配。

如果想要忽略以 '.' 開始的文件名,可將 '.*' 設(shè)置為 'GLOBIGNORE' 變量的其中一個(gè) pattern。'GLOBIGNORE' 變量未設(shè)置時(shí),'dotglob' 選項(xiàng)被關(guān)閉。

3.5.8.1 模式匹配


pattern 中的字符,除了下面描述的特殊 pattern 字符,將匹配其自身。NUL 字符不可出現(xiàn)在 pattern 中。

'' 字符將下面的特殊字符轉(zhuǎn)義為普通字符,以匹配其自身,匹配時(shí),'' 字符自身被忽略。

希望特殊字符匹配其自身時(shí),必須將其引用(quoted)。

'*'

匹配任意字符串,包括 空字符串。

shell 選項(xiàng) 'globstar' 開啟時(shí),'**' pattern 匹配所有文件和 0+ 個(gè)目錄及子目錄。

'**/' 只匹配目錄和子目錄。

'?'

匹配任意單個(gè)字符

'[...]'

匹配括號中任意一個(gè)字符。

一對以 '-' 分隔的字符表示 RANGE EXPRESSION(范圍表達(dá)式)。匹配這對字符之間(包括這對字符)的任意一個(gè)字符。

如果左括號 '[' 后面第一個(gè)字符是 '!' 或者 '^',匹配括號內(nèi)所有字符之外的
任意一個(gè)字符。

'-' 字符放在第一個(gè)位置,或最后一個(gè)位置時(shí),可以被匹配。

']' 字符放在第一個(gè)位置,可以被匹配。

范圍表達(dá)式的排序順序由當(dāng)前 locale 語系 和 'LC_COLLATE' (如果已設(shè)置)的值決定。

比如,根據(jù)默認(rèn)的 C locale,'[a-dx-z]' 等效于 '[abcdxyz]'。許多其他 locale 按照字典序排序,這時(shí) '[a-dx-z]' 可能等效于 '[aBbCcDdxXyYz]'。

可通過設(shè)置 'LC_COLLATE' 或 'LC_ALL' 為 'C',強(qiáng)制使用傳統(tǒng)的 'C' 語系排序。

在中括號中,CHARACTER CLASSES(特定字符集)可由 '[:'CLASS':]' 指定。

POSIX 標(biāo)準(zhǔn)定義的 CLASS 包括:

alnum   alpha   ascii   blank   cntrl   digit   graph
lower   print   punct   space   upper   word    xdigit

特定字符集可匹配屬于該字符集的任意一個(gè)字符。'word' 匹配 字母,數(shù)字 和 下劃線 '_'。

Within [ and ], an EQUIVALENCE CLASS can be specified usingthe syntax [=C=], which matches all characters with the same collation weight (as defined by the current locale) as the character C.

Within [ and ], the syntax [.SYMBOL.] matches the collating symbol SYMBOL.

如果 shell 選項(xiàng) 'extglob' 開啟(使用 'shopt' 命令),可使用下列的擴(kuò)展 pattern。在下面的描述中, PATTERN-LIST 是由 '|' 分隔的一個(gè)
或多個(gè) pattern 組成的列表。

復(fù)合 pattern 可由下面的一個(gè)或多個(gè) pattern 組成。

'?(PATTERN-LIST)'

匹配 0 個(gè)或 1個(gè) 給出的 patterns。

'*(PATTERN-LIST)'

匹配 0 個(gè)或 多個(gè) 給出的 patterns。

'+(PATTERN-LIST)'

匹配 1 個(gè)或 多個(gè) 給出的 patterns。

'@(PATTERN-LIST)'

匹配給出的 patterns 的其中一個(gè)。

'!(PATTERN-LIST)'

匹配給出的 patterns 之外的任意字符串。

3.5.9 引用取消


前面的展開完成之后,所有未被引用的 \,' 和 ",除了由之前的展開生成的,都被刪除。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容