当前位置: 首页 > Linux

Bash小技巧:使用参数展开来转换字符串的大小写和替换字符串

时间:2023-04-06 20:33:46 Linux

在bash中,通常使用${parameter}表达式来获取参数变量的值,这是参数展开的一种。Bash还提供了其他形式的参数扩展,可以对变量值做一些处理,起到操作字符串的作用。例如:${parameter^^pattern}将参数变量值中与pattern模式字符匹配的小写字母转换为大写。${parameter,,pattern}将参数变量值中匹配pattern模式字符的大写字母转换为小写。${parameter/pattern/string}将参数变量值中与模式pattern匹配的部分替换为字符串string。注意:这些表达式都不会修改参数本身的变量值,它们只是根据参数的变量值展开得到一个新的值。如果要保存这些值,则需要将它们分配给特定的变量。有关说明,请参阅manbash的参数扩展部分。具体例子如下。${parameter^^pattern}和${parameter,,pattern}查看manbash对${parameter^^pattern},${parameter^^pattern},${parameter,pattern},${parameter,,pattern}的说明如下:大小写修改。此扩展修改了参数中字母字符的大小写。模式被扩展以产生一个模式,就像在路径名扩展中一样。^运算符将匹配模式的小写字母转换为大写;,运算符将匹配的大写字母转换为小写字母。^^和,,扩展转换扩展值中的每个匹配字符;^和,扩展仅匹配并转换扩展值中的第一个字符。如果pattern被省略,它被视为匹配每个字符的?。如果parameter是@或*,则对每个位置参数依次进行大小写修改操作,展开就是结果列表。如果参数是@或*下标的数组变量,则应用大小写修改操作o数组的每个成员依次展开,并展开结果列表。即这四个表达式会匹配参数变量值中的patternpattern,对匹配到的字符进行大小写转换:^运算符将小写字母转换为大写,并且只转换开头的第一个字符,运算符转换大写字母转小写,只转换开头的第一个字符^^运算符将小写字母转换为大写,并将每个匹配的字符转换,,运算符将大写字母转换为小写,并转换每个匹配的字符。这里的pattern模式可以使用通配符进行扩展。请注意,它不是正则表达式。注意:^和,不转换为匹配到的第一个字符,只是转换参数变量值的第一个字符。给定的模式pattern必须匹配参数变量值的第一个字符才会被转换,字符串中间的字符不会被转换。具体例子如下:$value="ThisIsaTestString."$echo${value^t}ThisIsaTestString.$echo${value^^t}ThisIsaTesTSTring.$echo${value,T}这是一个测试字符串。$echo${value,,T}这是一个测试字符串。如您所见,使用${value^t}不会将value变量中间的小写t字符更改为大写。因为这个表达式只对值变量value的第一个字符进行匹配和转换,而值变量value不是以小写字母t开头,所以不进行转换。${value^^t}表达式将匹配值变量值中的每个小写字母t并将其转换为大写字母。所以输出中没有小写的t字符。同理,${value,T}表示将value变量value开头的大写T转为小写t。${value,,T}表示将value变量value的所有大写ts转为小写ts。如果省略patternmode,表示匹配任意字符,但不代表所有字符都会转换。^和,运算符仍然只转换第一个字符。以上面的值变量为例:echo${value,,}这是一个测试字符串。如您所见,${value^}只会将value变量的第一个字符更改为大写。由于它本来就是大写的,所以输出结果和值是一样的。${value^^}将所有字符转换为大写。${value,}将value变量value的第一个字符改为小写。${value,,}将所有字符转换为小写。注意:如果要匹配多个字符,必须用方括号[]将字符串括起来,并进行路径名扩展,得到多个可匹配的字符。将模式pattern直接写为字符串并不会匹配字符串中的每个字符。以上面的值变量为例:$echo${value,TI}ThisIsATestString.$echo${value,,TI}ThisIsaTestString.$echo${value,,[TI]}this是一个测试字符串。$echo${value,[TI]}这是一个测试字符串。可以看出,当给定的模式写成TI时,无论使用,还是,,都不能将大写的T和I转为小写。${value,TI}甚至不翻译前导T字符。而写${value,,[TI]}会将所有大写的T和I转换为小写。[TI]是路径名扩展的一种写法,表示匹配方括号[]中的每一个字符。基于字符的匹配,而不是基于字符串的匹配。写成${value,[TI]}表示将第一个字符T或第一个字符I转为小写,只匹配第一个字符。pathnameexpansion的具体写法请参考manbash的PathnameExpansion部分。最常见的是使用*通配符匹配零个或多个任意字符,并使用?匹配任何单个字符。上面的描述中提到,如果省略patternmode,就相当于写了?。即${parameter^^}等价于${parameter^^?}。${parameter/pattern/string}查看manbash对${parameter/pattern/string}的说明如下:模式替换。模式被扩展以产生一个模式,就像在路径名扩展中一样。参数被扩展,模式与其值的最长匹配被替换为字符串。如果pattern以/开头,则pattern的所有匹配项都将替换为string。通常只替换第一个匹配项。如果pattern以#开头,则必须匹配参数扩展值的开头。如果pattern以%开头,则它必须在参数扩展值的末尾匹配。如果string为null,则删除模式的匹配项,并且可以省略/后面的模式。如果参数是@或*,替换操作依次应用于每个位置参数,扩展是结果列表。如果参数是下标为@或*的数组变量,则替换操作依次应用于数组的每个成员,并且展开ion是结果列表。即${parameter/pattern/string}表达式可以替换参数变量值的字符串。给定的patternpattern会按照路径名扩展方式进行扩展,然后根据参数变量值进行扩展。其值中与patternlongest匹配的部分将替换为string指定的字符串。如果pattern以/开头,则所有出现的pattern都将替换为字符串。通常只替换第一个匹配项。如果patternpattern以#开头,则必须从头匹配参数变量值。如果patternpattern以%开头,则必须从后往前匹配参数变量值。如果string字符串为空,则删除匹配patternpattern的地方,patternpattern后面的/字符可以省略。具体例子如下:$value="Thisisateststring.Thisisanewtest"$echo${value/test/TEST}ThisisaTESTstring。这是一个新的test$echo${value//test/TEST}这是一个TEST字符串。这是一个新的TEST$echo${value/#test/TEST}这是一个测试字符串。这是一个新的test$echo${value/#This/THIS}THIS是一个测试字符串。这是一个新的测试$echo${value/%test/TEST}这是一个测试字符串。这是一个新的TEST$echo${value/test}这是一个字符串。这是一个新的测试$echo${value//test}这是一个字符串。这是一个新的可以看到,在${value/test/TEST}表达式中,value变量value是要替换的原始字符串。中间的test是要替换的模式,只会替换第一次出现的“test”字符串,不会替换所有的“test”字符串。下面的TEST是替换后的内容。最终输出结果是将value变量value中第一个“test”字符串替换为“TEST”,第二个“test”字符串不替换。${value//test/TEST}表达式的“/test”模式以/开头,表示替换所有出现的“test”字符串。输出中所有出现的“test”都替换为“TEST”。${value/#test/TEST}表达式的“#test”模式以#开头,表示从value变量值的第一个字符开始匹配。由于value变量的值不是以“test”开头,所以无法匹配,不进行替换。使用${value/#This/THIS}将value变量值开头的"This"替换为"THIS"。${value/%test/TEST}表达式类似,要求从value变量value的末尾开始匹配“test”字符串。这两个都从最后一个字符开始匹配。${value/test}表达式,没有替换的字符串参数,意味着从值变量值中删除第一次出现的“测试”字符串。${value//test}表达式的“/test”模式以/开头,表示从值变量值中删除所有出现的“test”字符串。上面提到的“最长匹配”部分被替换。所谓“最长匹配”,是指模式pattern所包围的最长部分。通配符用于匹配多个字符形成嵌套时很常见。具体例子如下:$value="Thisisa|teststring|newtest|,checkit"$echo${value/|*|/NEWSTRING}ThisisaNEWSTRING,checkit$echo${value/|*|}这是一个,检查一下可以看到给定的匹配模式是|*|。使用*通配符匹配两个|s之间的任何字符串。两种形式“|测试字符串|”和“|测试字符串|新测试|”在给定的值变量中匹配此模式。实际上替换的是最后一个,也就是最长的匹配。由于模式不以/开头,因此只处理第一个匹配项,所以“|newtest|”不会匹配。即当patternmode的展开结果为变长字符串时,会有前缀部分,中间有变长部分,后缀部分。然后最长匹配从前缀部分开始,直到最后匹配到后缀部分,而不是遇到第一个匹配到的后缀部分就停止。中间可变长度部分可以包含多个前缀部分和后缀部分。这里还有一个例子如下:$value="Thisisateststring,firstcheckit"$echo${value/t*st}Thisisacheckit可以看到在给定的value变量值中,t*的st模式的后缀部分“st”匹配“first”字符串之后的“st”。而不是匹配“test”字符串的“st”。最后的结果是最长的匹配部分。