shell脚本自由操作字符串

字符串长度

${#string}expr length $stringexpr "$string" : '.*'

1stringZ=abcABC123ABCabc
2
3echo${#stringZ}#15
4echo`exprlength$stringZ`#15
5echo`expr"$stringZ":'.*'`#15


例子 9-10. 在一个文本文件的段落之间插入空行

1#!/bin/bash
2#paragraph-space.sh
3
4#在一个单倍行距的文本文件中插入空行.
5#Usage:$0


匹配字符串开头的子串长度

expr match "$string" '$substring'

$substring一个正则表达式.

expr "$string" : '$substring'

一个正则表达式.

1stringZ=abcABC123ABCabc
2#|------|
3
4echo`exprmatch"$stringZ"'abc[A-Z]*.2'`#8
5echo`expr"$stringZ":'abc[A-Z]*.2'`#8


索引

expr index $string $substring

在字符串$string中所匹配到的$substring第一次所出现的位置.

1stringZ=abcABC123ABCabc
2echo`exprindex"$stringZ"C12`#6
3#C字符的位置.
4
5echo`exprindex"$stringZ"1c`#3
6#'c'(in#3position)matchesbefore'1'.


提取子串这与C语言中的strchr()函数非常相似.

${string:position}

$string中从位置$position开始提取子串.

如果是"*"或者"@",那么将会提取从位置开始的位置参数.[1]

${string:position:length}

开始提取$length长度的子串.

1stringZ=abcABC123ABCabc
2#0123456789.....
3#0-basedindexing.
4
5echo${stringZ:0}#abcABC123ABCabc
6echo${stringZ:1}#bcABC123ABCabc
7echo${stringZ:7}#23ABCabc
8
9echo${stringZ:7:3}#23A
10#提取子串长度为3.
11
12
13
14#能不能从字符串的右边(也就是结尾)部分开始提取子串?
15
16echo${stringZ:-4}#abcABC123ABCabc
17#认是提取整个字符串,就象${parameter:-default}一样.
18#然而...
19
20echo${stringZ:(-4)}#Cabc
21echo${stringZ:-4}#Cabc
22#这样,它就可以工作了.
23#使用圆括号或者添加一个空格可以"转义"这个位置参数.

参数是"*"或"@",那么将会从位置开始提取个位置参数,但是由于可能没有个位置参数了,那么就有几个位置参数就提取几个位置参数.

1echo${*:2}#打印出第2个和后边所有的位置参数.
2echo${@:2}#同上.
3
4echo${*:2:3}#从第2个开始,连续打印3个位置参数.

中从长度的子串.expr substr $string $position $length

1stringZ=abcABC123ABCabc
2#123456789......
3#以1开始计算.
4
5echo`exprsubstr$stringZ12`#ab
6echo`exprsubstr$stringZ43`#ABC

的开始位置提取,.expr match "$string" '\($substring\)'

expr "$string" : '\($substring\)'

是正则表达式.

1stringZ=abcABC123ABCabc
2#=======
3
4echo`exprmatch"$stringZ"'\(.[b-c]*[A-Z]..[0-9]\)'`#abcABC1
5echo`expr"$stringZ":'\(.[b-c]*[A-Z]..[0-9]\)'`#abcABC1
6echo`expr"$stringZ":'\(.......\)'`#abcABC1
7#上边的每个echo都打印出相同的结果.


的结尾提取是正则表达式.expr match "$string" '.*\($substring\)'

expr "$string" : '.*\($substring\)'

是正则表达式.

1stringZ=abcABC123ABCabc
2#======
3
4echo`exprmatch"$stringZ"'.*\([A-C][A-C][A-C][a-c]*\)'`#ABCabc
5echo`expr"$stringZ":'.*\(......\)'`#ABCabc

${string#substring}子串削除

的开头位置截掉最短匹配的${string##substring}

的开头位置截掉最长匹配的.

1stringZ=abcABC123ABCabc
2#|----|
3#|----------|
4
5echo${stringZ#a*C}#123ABCabc
6#截掉'a'到'C'之间最短的匹配字符串.
7
8echo${stringZ##a*C}#abc
9#截掉'a'到'C'之间最长的匹配字符串.

的结尾位置截掉最短匹配的${string%substring}

${string%%substring}

的结尾位置截掉最长匹配的.

1stringZ=abcABC123ABCabc
2#||
3#|------------|
4
5echo${stringZ%b*c}#abcABC123ABCa
6#从$stringZ的结尾位置截掉'b'到'c'之间最短的匹配.
7
8echo${stringZ%%b*c}#a
9#从$stringZ的结尾位置截掉'b'到'c'之间最长的匹配.

当你需要构造文件名的时候,这个操作就显得特别有用.


例子 9-11. 转换图片文件格式,同时更改文件名

1#!/bin/bash
2#cvt.sh:
3#将一个目录下的所有MacPaint格式的图片文件都转换为"pbm"各式的图片文件.
4
5#使用"netpbm"包中的"macptopbm"程序进行转换,6#+这个程序主要是由BrianHenderson(bryanh@giraffe-data.com)来维护的.
7#Netpbm绝大多数Linux发行版的标准套件.
8
9PERATION=macptopbm
10SUFFIX=pbm#新的文件名后缀.
11
12if[-n"$1"]
13then
14directory=$1#如果目录名作为参数传递给脚本...
15else
16directory=$PWD#否则使用当前的工作目录.
17fi
18
19#假定目标目录中的所有文件都是MacPaint格式的图像文件,20#+并且都是以".mac"作为文件名后缀.
21
22forfilein$directory/*#文件名匹配(filenameglobbing).
23do
24filename=${file%.*c}#去掉文件名的".mac"后缀
25#+('.*c'将会匹配
26#+'.'和'c'之间任意字符串).
27$OPERATION$file>"$filename.$SUFFIX"
28#把结果重定向到新的文件中.
29rm-f$file#转换后删除原始文件.
30echo"$filename.$SUFFIX"#从stdout输出转换后文件的文件名.
31done
32
33exit0
34
35#练习:
36#-----
37#就像它现在的样子,这个脚本把当前
38#+目录下的所有文件都转换了.
39#修改这个脚本,让它只转换以".mac"为后缀名的文件.



例子 9-12. 将音频流文件转换为ogg各式的文件

1#!/bin/bash
2#ra2ogg.sh:将音频流文件(*.ra)转换为ogg格式的文件.
3
4#使用"mplayer"媒体播放器程序:
5#http://www.mplayerhq.hu/homepage
6#可能需要安装合适的编解码程序(codec)才能够正常的运行这个脚本.
7#需要使用"ogg"库和"oggenc":
8#http://www.xiph.org/
9
10
11FILEPREF=${1%%ra}#去掉"ra"后缀.
12FILESUFF=wav#wav文件的后缀.
13UTFILE="$OFILEPREF""$OFILESUFF"
14E_NOARGS=65
15
16if[-z"$1"]#必须要指定一个需要转换的文件名.
17then
18echo"Usage:`basename$0`[filename]"
19exit$E_NOARGS
20fi
21
22
23##########################################################################
24mplayer"$1"-aopcm:file=$OUTFILE
25oggenc"$OUTFILE"#oggenc编码后会自动加上正确的文件扩展名.
26##########################################################################
27
28rm"$OUTFILE"#删除中介的*.wav文件.
29#如果你想保留这个文件的话,可以把上边这行注释掉.
30
31exit$?
32
33#注意:
34#----
35#在网站上,简单的在*.ram流音频文件上单击的话,36#+一般都只会下载真正音频流文件(就是*.ra文件)的URL.
37#你可以使用"wget"或者一些类似的工具
38#+来下载*.ra文件本身.
39
40
41#练习:
42#-----
43#像上面所看到的,这个脚本只能够转换*.ra文件.
44#给这个脚本添加一些灵活性,让它能够转换*.ramandotherfilenames.
45#
46#如果你觉得这还不过瘾,那么你可以扩展这个脚本,47#+让它自动下载并转换音频流文件.
48#给出一个URL,(使用"wget")批处理下载音频流文件,49#+然后转换它们.

一个简单的getopt命令的模拟,使用子串提取结构.




例子 9-13. 模拟getopt

1#!/bin/bash
2#getopt-simple.sh
3#作者:ChrisMorgan
4#已经经过授权,可以使用在本书中.
5
6
7getopt_simple()
8{
9echo"getopt_simple()"
10echo"Parametersare'$*'"
11until[-z"$1"]
12do
13echo"Processingparameterof:'$1'"
14if[${1:0:1}='/']
15then
16tmp=${1:1}#去掉开头的'/'...
17parameter=${tmp%%=*}#提取参数名.
18value=${tmp##*=}#提取参数值.
19echo"Parameter:'$parameter',value:'$value'"
20eval$parameter=$value
21fi
22shift
23done
24}
25
26#把所有选项传给函数getopt_simple().
27getopt_simple$*
28
29echo"testis'$test'"
30echo"test2is'$test2'"
31
32exit0
33
34---
35
36shgetopt_example.sh/test=value1/test2=value2
37
38Parametersare'/test=value1/test2=value2'
39Processingparameterof:'/test=value1'
40Parameter:'test',value:'value1'
41Processingparameterof:'/test2=value2'
42Parameter:'test2',value:'value2'
43testis'value1'
44test2is'value2'

子串替换

${string/substring/replacement}

使用$replacement来替换第一个匹配的${string//substring/replacement}

来替换所有匹配的.

1stringZ=abcABC123ABCabc
2
3echo${stringZ/abc/xyz}#xyzABC123ABCabc
4#使用'xyz'来替换第一个匹配的'abc'.
5
6echo${stringZ//abc/xyz}#xyzABC123ABCxyz
7#用'xyz'来替换所有匹配的'abc'.

匹配的开头部分,那么就用来替换${string/#substring/replacement}
${string/%substring/replacement}

的结尾部分,255);">.

1stringZ=abcABC123ABCabc
2
3echo${stringZ/#abc/XYZ}#XYZABC123ABCabc
4#用'XYZ'替换开头的'abc'.
5
6echo${stringZ/%abc/XYZ}#abcABC123ABCXYZ
7#用'XYZ'替换结尾的'abc'.


9.2.1. 使用awk来处理字符串

Bash脚本也可以调用awk的字符串操作功能来代替它自己内建的字符串操作.


例子 9-14. 提取字符串的另一种方法

1#!/bin/bash
2#substring-extraction.sh
3
4String=23skidoo1
5#012345678Bash
6#123456789awk
7#注意不同的字符串索引系统:
8#Bash的第一个字符是从'0'开始记录的.
9#Awk的第一个字符是从'1'开始记录的.
10
11echo${String:2:4}#位置3(0-1-2),4个字符长
12#skid
13
14#awk中等价于${string:pos:length}的命令是substr(string,pos,length).
15echo|awk'
16{printsubstr("'"${String}"'",4)#skid
17}
18'
19#使用一个空的"echo"通过管道传递给awk一个假的输入,20#+这样就不必提供一个文件名给awk.
21
22exit0

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...