Linux Shell 学习笔记(1)——字符串操作

  Bash shell 学习笔记(1)——字符串操作

  1.字符串的长度

  获取字符串长度的语法如下。

${#varname}

  下面是一个例子。

$ myPath=/home/cam/book/long.file.name
$ echo ${#myPath}
29

  大括号{}是必需的,否则 Bash 会将$#理解成脚本的参数个数,将变量名理解成文本。

$ echo $#myvar
0myvar

  上面例子中,Bash 将$#和myvar分开解释了。

  2.子字符串

  字符串提取子串的语法如下。

${varname:offset:length}
  上面语法的含义是返回变量$varname的子字符串,从位置offset开始(从0开始计算),长度为length。

$ count=frogfootman
$ echo ${count:4:4}
foot

  上面例子返回字符串frogfootman从4号位置开始的长度为4的子字符串foot。

  这种语法不能直接操作字符串,只能通过变量来读取字符串,并且不会改变原始字符串。变量前面的美元符号可以省略。

# 报错
$ echo ${"hello":2:3}

  上面例子中,"hello"不是变量名,导致 Bash 报错。

  如果省略length,则从位置offset开始,一直返回到字符串的结尾。

$ count=frogfootman
$ echo ${count:4}
footman

  上面例子是返回变量count从4号位置一直到结尾的子字符串。

  如果offset为负值,表示从字符串的末尾开始算起。注意,负数前面必须有一个空格, 以防止与${variable:-word}的变量的设置默认值语法混淆。这时还可以指定length,length可以是正值,也可以是负值(负值不能超过offset的长度)。

$ foo="This string is long."
$ echo ${foo: -5}
long.
$ echo ${foo: -5:2}
lo
$ echo ${foo: -5:-2}
lon

  上面例子中,offset为-5,表示从倒数第5个字符开始截取,所以返回long.。如果指定长度length为2,则返回lo;如果length为-2,表示要排除从字符串末尾开始的2个字符,所以返回lon。

  3.搜索和替换

Bash 提供字符串搜索和替换的多种方法。

  (1)字符串头部的模式匹配。

  以下两种语法可以检查字符串开头,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,返回剩下的部分。原始变量不会发生变化。

# 如果 pattern 匹配变量 variable 的开头,
# 删除最短匹配(非贪婪匹配)的部分,返回剩余部分
${variable#pattern}

# 如果 pattern 匹配变量 variable 的开头,
# 删除最长匹配(贪婪匹配)的部分,返回剩余部分
${variable##pattern}

上面两种语法会删除变量字符串开头的匹配部分(将其替换为空),返回剩下的部分。区别是一个是最短匹配(又称非贪婪匹配),另一个是最长匹配(又称贪婪匹配)。

匹配模式pattern可以使用*、?、[]等通配符。

$ myPath=/home/cam/book/long.file.name

$ echo ${myPath#/*/}
cam/book/long.file.name

$ echo ${myPath##/*/}
long.file.name

  上面例子中,匹配的模式是//,其中可以匹配任意数量的字符,所以最短匹配是/home/,最长匹配是/home/cam/book/。

  下面写法可以删除文件路径的目录部分,只留下文件名。

$ path=/home/cam/book/long.file.name

$ echo ${path##*/}
long.file.name

  上面例子中,模式*/匹配目录部分,所以只返回文件名。

下面再看一个例子。

$ phone="555-456-1414"
$ echo ${phone#*-}
456-1414
$ echo ${phone##*-}
1414

  如果匹配不成功,则返回原始字符串。

$ phone="555-456-1414"
$ echo ${phone#444}
555-456-1414

上面例子中,原始字符串里面无法匹配模式444,所以原样返回。

  如果要将头部匹配的部分,替换成其他内容,采用下面的写法。

# 模式必须出现在字符串的开头
${variable/#pattern/string}

# 示例
$ foo=JPG.JPG
$ echo ${foo/#JPG/jpg}
jpg.JPG

  上面例子中,被替换的JPG必须出现在字符串头部,所以返回jpg.JPG。

  (2)字符串尾部的模式匹配。

  以下两种语法可以检查字符串结尾,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,返回剩下的部分。原始变量不会发生变化。

# 如果 pattern 匹配变量 variable 的结尾,
# 删除最短匹配(非贪婪匹配)的部分,返回剩余部分
${variable%pattern}

# 如果 pattern 匹配变量 variable 的结尾,
# 删除最长匹配(贪婪匹配)的部分,返回剩余部分
${variable%%pattern}

  上面两种语法会删除变量字符串结尾的匹配部分(将其替换为空),返回剩下的部分。区别是一个是最短匹配(又称非贪婪匹配),另一个是最长匹配(又称贪婪匹配)。

$ path=/home/cam/book/long.file.name

$ echo ${path%.*}
/home/cam/book/long.file
  注意:“%”是指从左往右遇到的最后一个pattern,如示例中的最后一个“ . ”符合,之后的内容均被 “ * ”通配符选中而删除。
$ echo ${path%%.*}
/home/cam/book/long
  而 “%%”是指从右往左遇到的第一个pattern,删除该pattern和之后的内容。如示例中被选中的删除内容就是.file.name,若我们该为 echo ${path%%a*} 则结果为/home/c

  上面例子中,匹配模式是.,其中可以匹配任意数量的字符,所以最短匹配是.name,最长匹配是.file.name。

  下面写法可以删除路径的文件名部分,只留下目录部分。

$ path=/home/cam/book/long.file.name

$ echo ${path%/*}
/home/cam/book

  上面例子中,模式/*匹配文件名部分,所以只返回目录部分。

  下面的写法可以替换文件的后缀名。

$ file=foo.png
$ echo ${file%.png}.jpg
foo.jpg

  上面的例子将文件的后缀名,从.png改成了.jpg。

  下面再看一个例子。

$ phone="555-456-1414"
$ echo ${phone%-*}
555-456
$ echo ${phone%%-*}
555

  如果匹配不成功,则返回原始字符串。

  如果要将尾部匹配的部分,替换成其他内容,采用下面的写法。

# 模式必须出现在字符串的结尾
${variable/%pattern/string}

# 示例
$ foo=JPG.JPG
$ echo ${foo/%JPG/jpg}
JPG.jpg

  上面例子中,被替换的JPG必须出现在字符串尾部,所以返回JPG.jpg。

(3)任意位置的模式匹配。

  以下两种语法可以检查字符串内部,是否匹配给定的模式。如果匹配成功,就删除匹配的部分,换成其他的字符串返回。原始变量不会发生变化。

# 如果 pattern 匹配变量 variable 的一部分,
# 最长匹配(贪婪匹配)的那部分被 string 替换,但仅替换第一个匹配
${variable/pattern/string}

# 如果 pattern 匹配变量 variable 的一部分,
# 最长匹配(贪婪匹配)的那部分被 string 替换,所有匹配都替换
${variable//pattern/string}

  上面两种语法都是最长匹配(贪婪匹配)下的替换,区别是前一个语法仅仅替换第一个匹配,后一个语法替换所有匹配。

$ path=/home/cam/foo/foo.name

$ echo ${path/foo/bar}
/home/cam/bar/foo.name

$ echo ${path//foo/bar}
/home/cam/bar/bar.name

  上面例子中,前一个命令只替换了第一个foo,后一个命令将两个foo都替换了。

  下面的例子将分隔符从:换成换行符。

$ echo -e ${PATH//:/'\n'}
/usr/local/bin
/usr/bin
/bin
...

  上面例子中,echo命令的-e参数,表示将替换后的字符串的\n字符,解释为换行符。

  模式部分可以使用通配符。

$ phone="555-456-1414"
$ echo ${phone/5?4/-}
55-56-1414

  上面的例子将5-4替换成-。

  如果省略了string部分,那么就相当于匹配的部分替换成空字符串,即删除匹配的部分。

$ path=/home/cam/foo/foo.name

$ echo ${path/.*/}
/home/cam/foo/foo

  上面例子中,第二个斜杠后面的string部分省略了,所以模式.*匹配的部分.name被删除后返回。

  前面提到过,这个语法还有两种扩展形式。

# 模式必须出现在字符串的开头
${variable/#pattern/string}

# 模式必须出现在字符串的结尾
${variable/%pattern/string}
改变大小写

  下面的语法可以改变变量的大小写。

# 转为大写
${varname^^}

# 转为小写
${varname,,}

  下面是一个例子。

$ foo=heLLo
$ echo ${foo^^}
HELLO
$ echo ${foo,,}
hello

  变量

  注:教程来源于网道 Bash脚本,博主仅做个人学习的笔记。
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~晨曦静竹~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值