字符串操作
本章介绍 Bash 字符串操作的语法。
字符串的长度
获取字符串长度的语法如下。
1 |
|
下面是一个例子。
1 |
|
大括号{}
是必需的,否则 Bash 会将$#
理解成脚本的参数个数,将变量名理解成文本。
1 |
|
上面例子中,Bash 将$#
和myvar
分开解释了。
子字符串
字符串提取子串的语法如下。
1 |
|
上面语法的含义是返回变量$varname
的子字符串,从位置offset
开始(从0
开始计算),长度为length
。
1 |
|
上面例子返回字符串frogfootman
从4号位置开始的长度为4的子字符串foot
。
这种语法不能直接操作字符串,只能通过变量来读取字符串,并且不会改变原始字符串。变量前面的美元符号可以省略。
1 |
|
上面例子中,"hello"
不是变量名,导致 Bash 报错。
如果省略length
,则从位置offset
开始,一直返回到字符串的结尾。
1 |
|
上面例子是返回变量count
从4号位置一直到结尾的子字符串。
如果offset
为负值,表示从字符串的末尾开始算起。注意,负数前面必须有一个空格, 以防止与${variable:-word}
的变量的设置默认值语法混淆。这时还可以指定length
,length
可以是正值,也可以是负值(负值不能超过offset
的长度)。
1 |
|
上面例子中,offset
为-5
,表示从倒数第5个字符开始截取,所以返回long.
。如果指定长度length
为2
,则返回lo
;如果length
为-2
,表示要排除从字符串末尾开始的2个字符,所以返回lon
。
搜索和替换
Bash 提供字符串搜索和替换的多种方法。
(1)字符串头部的模式匹配。
以下两种语法可以检查字符串开头,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,返回剩下的部分。原始变量不会发生变化。
1 |
|
上面两种语法会删除变量字符串开头的匹配部分(将其替换为空),返回剩下的部分。区别是一个是最短匹配(又称非贪婪匹配),另一个是最长匹配(又称贪婪匹配)。
匹配模式pattern
可以使用*
、?
、[]
等通配符。
1 |
|
上面例子中,匹配的模式是/*/
,其中*
可以匹配任意数量的字符,所以最短匹配是/home/
,最长匹配是/home/cam/book/
。
下面写法可以删除文件路径的目录部分,只留下文件名。
1 |
|
上面例子中,模式*/
匹配目录部分,所以只返回文件名。
下面再看一个例子。
1 |
|
如果匹配不成功,则返回原始字符串。
1 |
|
上面例子中,原始字符串里面无法匹配模式444
,所以原样返回。
如果要将头部匹配的部分,替换成其他内容,采用下面的写法。
1 |
|
上面例子中,被替换的JPG
必须出现在字符串头部,所以返回jpg.JPG
。
(2)字符串尾部的模式匹配。
以下两种语法可以检查字符串结尾,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,返回剩下的部分。原始变量不会发生变化。
1 |
|
上面两种语法会删除变量字符串结尾的匹配部分(将其替换为空),返回剩下的部分。区别是一个是最短匹配(又称非贪婪匹配),另一个是最长匹配(又称贪婪匹配)。
1 |
|
上面例子中,匹配模式是.*
,其中*
可以匹配任意数量的字符,所以最短匹配是.name
,最长匹配是.file.name
。
下面写法可以删除路径的文件名部分,只留下目录部分。
1 |
|
上面例子中,模式/*
匹配文件名部分,所以只返回目录部分。
下面的写法可以替换文件的后缀名。
1 |
|
上面的例子将文件的后缀名,从.png
改成了.jpg
。
下面再看一个例子。
1 |
|
如果匹配不成功,则返回原始字符串。
如果要将尾部匹配的部分,替换成其他内容,采用下面的写法。
1 |
|
上面例子中,被替换的JPG
必须出现在字符串尾部,所以返回JPG.jpg
。
(3)任意位置的模式匹配。
以下两种语法可以检查字符串内部,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,换成其他的字符串返回。原始变量不会发生变化。
1 |
|
上面两种语法都是最长匹配(贪婪匹配)下的替换,区别是前一个语法仅仅替换第一个匹配,后一个语法替换所有匹配。
1 |
|
上面例子中,前一个命令只替换了第一个foo
,后一个命令将两个foo
都替换了。
下面的例子将分隔符从:
换成换行符。
1 |
|
上面例子中,echo
命令的-e
参数,表示将替换后的字符串的\n
字符,解释为换行符。
模式部分可以使用通配符。
1 |
|
上面的例子将5-4
替换成-
。
如果省略了string
部分,那么就相当于匹配的部分替换成空字符串,即删除匹配的部分。
1 |
|
上面例子中,第二个斜杠后面的string
部分省略了,所以模式.*
匹配的部分.name
被删除后返回。
前面提到过,这个语法还有两种扩展形式。
1 |
|
改变大小写
下面的语法可以改变变量的大小写。
1 |
|
下面是一个例子。
1 |
|