十 字符串处理

Posted 钟桂耀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十 字符串处理相关的知识,希望对你有一定的参考价值。

 

变量子串常用操作:

 

表达式含义
${#string} $string的长度
   
${string:position} 在$string中, 从位置$position开始提取子串
${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串
   
${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串
   
${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

说明:

$substring可以是一个正则表达式.

 

 

返回长度

 

${#string} :返回$string的长度

 

 

字符串截取

 

 

字符串截取            格式                                           
使用${}表达式         ${var:起始位置:长度};编号从0开始,可省略                
使用expr substr      expr substr "$var" 起始位置 长度;起始位置编号从1开始
使用cut工具        echo $var | cut -b 起始位置-结束位置;起始位置编号从1开始

说明:

${string:position}           在$string中, 从位置$position开始提取子串
${string:position:length}    在$string中, 从位置$position开始提取长度为$length的子串

 

 

 

 

 

字符串的匹配删除

 

 

     格式                         
${变量名#*关键词}      从左到右,最短匹配删除;#用来删除头部,*通配 
${变量名##*关键词}     从左到右,最长匹配删除;#用来删除头部,*通配    

${变量名%关键词*}      从右到左,最短匹配删除;%用来删除尾部,*通配    
${变量名%%关键词*}     从右到左,最长匹配删除;%用来删除尾部,*通配   

 

解析:

${string#substring}    从变量$string的开头, 删除最短匹配$substring的子串
${string##substring}    从变量$string的开头, 删除最长匹配$substring的子串
${string%substring}    从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring}    从变量$string的结尾, 删除最长匹配$substring的子串

 

 

文件批量改名

 

 

 

例子:将扩展名.doc改为.txt

 


#!/bin/bash
for FILE in *.doc
do
  mv $FILE ${FILE%.doc}.txt
done

 

 

字符串的替换

 

 

 

 

 

    格式
${var/old/new}           只替换第一个匹配结果   
${var//old/new}          替换全部匹配结果    
${string/#substring/replace}   如果$string前缀匹配$substring,就用$replace来代替匹配$substring
${string/%substring/replace}   如果$string后缀匹配$substring,就用$replace来代替匹配$substring

 

解析:

${string/substring/replacement}     使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement}     使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement}     如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement}     如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

 

 

 依次举例说明:


定义OLDBOY变量,内容为”I am oldboy”


I am oldboy

1)返回字符串OLDBOY变量字符串的长度

[root@Web ~]# echo ${#OLDBOY}

11

[root@Web ~]# echo ${OLDBOY} |wc -m

12

2)截取OLDBOY变量字符串从第2个字符之后开始取,默认取后面字符的全部,第2个字符不包括在内。也可理解为删除前面的多少个字符

[root@Web ~]# echo ${OLDBOY:2}

am oldboy

 

3)截取OLDBOY变量字符串从第2个字符之后开始取,取两个字符。

[root@Web ~]# echo ${OLDBOY:2:2}

am

提示:类似cut -c参数

[root@Web ~]# echo ${OLDBOY}|cut -c 1-4

I am

[root@Web ~]# echo ${OLDBOY}|cut -c 3-4

am

4)从变量$OLDBOY开头开始删除最短匹配”I am”子串

[root@Web ~]# echo ${OLDBOY#I am}

oldboy

 

5)从变量$OLDBOY开头开始删除最长匹配”I am old”子串

[root@Web ~]# echo ${OLDBOY##I am old}

boy

6)从变量$OLDBOY结尾开始删除最短匹配oldboy子串

[root@Web ~]# echo ${OLDBOY%oldboy}

I am

7)从变量$OLDBOY结尾开始删除最长匹配boy子串

[root@Web ~]# echo ${OLDBOY%%boy}

I am old

8)使用etiantian字符串,来代替变量$OLDBOY第一个匹配的oldboy字符串

[root@Web ~]# echo ${OLDBOY/oldboy/etiantian}

I am etiantian

 

9)使用etiantian字符串,来代替变量$OLDBOY结尾匹配的oldboy字符串

[root@Web ~]# echo ${OLDBOY/%oldboy/etiantian}

I am etiantian

10)使用He is字符串,来代替从变量$OLDBOY开头开始匹配的I am字符串

[root@Web ~]# echo ${OLDBOY/#I am/He is}

He is oldboy

 

 

生产场景用法实例:

1)变量结尾删除生产实践:

 

功能描述如下表:

 

 

${string#substring}     从变量$string的开头, 删除最短匹配$substring的子串

 

 批量文件改名案例实践:

问题1:把下面所有的文件名中的finishied内容去掉。
[root@localhost ~]# mkdir /test
[root@localhost ~]# cd /test
[root@localhost test]# cat a.log 
stu_102999_2_finish.jpg
stu_102999_3_finish.jpg
stu_102999_4_finish.jpg
[root@localhost test]# for f in `cat a.log`;do touch $f;done
[root@localhost test]# ll
总用量 4
-rw-r--r--. 1 root root 72 3月  30 22:24 a.log
-rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_2_finish.jpg
-rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_3_finish.jpg
-rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_4_finish.jpg


[root@localhost test]# cat p.sh 
for f in `ls *.jpg` 
do 
    mv $f `echo ${f%finish*}.jpg`
done

[root@localhost test]# ll
总用量 8
-rw-r--r--. 1 root root 72 3月  30 22:24 a.log
-rw-r--r--. 1 root root  0 3月  30 22:24 cat
-rw-r--r--. 1 root root 64 3月  30 22:49 p.sh
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.jpg
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.jpg
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.jpg

 

 

2)变量结尾替换生产实践:

 

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

 

 

 

问题:把下面文件的大写扩展名变小写扩展名

[root@localhost test]# cat p.sh
for f in `ls *.jpg` 
do 
    mv $f `echo "${f/%jpg/JPG}"`
done
[root@localhost test]# sh p.sh
[root@localhost test]# ll
总用量 8
-rw-r--r--. 1 root root 72 3月  30 22:24 a.log
-rw-r--r--. 1 root root  0 3月  30 22:24 cat
-rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.JPG
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.JPG
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.JPG

 

 1 命令名称:rename-Rename files

2 命令功能:给文件重命名

3命令语法: rename from to file 提示:这里的用法”from to file”一开始会被大家误解,实际上还是看下面表格吧:

 

 

 

还是看实际例子吧!

准备测试数据:

 

[root@Web ~]# mkdir /test
[root@Web ~]# cd /test
[root@Web test]# for f in `seq 9`;do touch foo$f.htm;done
[root@Web test]# ls -l
总用量 0
-rw-r--r--. 1 root root 0 4月  12 21:58 foo1.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo2.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo3.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo4.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo5.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo6.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo7.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo8.htm
-rw-r--r--. 1 root root 0 4月  12 21:58 foo9.htm

[root@localhost test]# rename .JPG .htm *.JPG
[root@localhost test]# ll
总用量 8
-rw-r--r--. 1 root root 72 3月  30 22:24 a.log
-rw-r--r--. 1 root root  0 3月  30 22:24 cat
-rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.htm
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.htm
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.htm


[root@localhost test]# rename 102999 oldboy *.htm
[root@localhost test]# ll
总用量 8
-rw-r--r--. 1 root root 72 3月  30 22:24 a.log
-rw-r--r--. 1 root root  0 3月  30 22:24 cat
-rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_oldboy_2_.htm
-rw-r--r--. 1 root root  0 3月  30 22:48 stu_oldboy_3_.htm

 

 

 

 

更多批量改名案例,请看老男孩的博文《Linux下批量修改文件名精彩解答案例分享》

https://blog.51cto.com/oldboy/711342

 

 

变量初值处理

 

 

 

取值

 

 

取值,${var:-word}

 

 


若变量var已存在且非null,则返回$var的值
否则返回字串"word",变量var值不变
用途: 如果变量没定义 返回默认值

 

 

赋值

 

赋值,${var:=word}

若变量var已存在且非null,则返回$var的值
否则返回字串"word",并赋值给变量var
用途: 如果变量没定义 给变量赋值

 

 

 

 

 

有值时提示

 

 

 

有值时提示,${var:+"提示信息"}

若变量var已存在且非null,则给出提示
否则返回NUll(空值)
用途 : 测试变量是否定义

 

 

 

无值时提示

 

 

 

无值时提示,${var:?"提示信息"}

若变量var已存在且非null,则返回$var的值
否则给出提示信息(若省略,则用默认提示)
用途: 捕捉由于变量未定义所导致的错误

 

 

 

练习:

 

a、提示输入一个正整数x,求从1x的和

 

b、若用户未输入值(直接回车),则赋值x=1

 

#!/bin/bash
read -p "请输入一个正整数:" x
x=${x:-1};i=1;SUM=0
while [ $i -le $x ]
do
  let SUM+=i;let i++
done
echo "从1到$x的总和是:$SUM"

 

 

 

 

 

例题:

 

mycluster.sh

 

检查集群中主机的物理连接状态,要求如下

 

能够设置检查主机的台数 和 检查哪些主机

 

把不在线主机的ip地址和时间保存到/clusterdir目录下的stat.txt文件里并把不在线主机的ip地址 时间 台数 输出到屏幕上

 

 

 

 

 

 

下面一次举例说明:

1${value:-word}  

当变量未定义或者值为空时,返回值为word内容,否则返回变量的值

举例:

[zgy@Web ~]$ result=${test:-UNSET}

[zgy@Web ~]$ echo $result

UNSET

[zgy@Web ~]$ echo $test

            ==>这里是空

结论:当test变量没内容时,就返回了后面的UNSET.

 

[zgy@Web ~]$ test=\'oldboy\'

[zgy@Web ~]$ result=${test:-UNSET}

[zgy@Web ~]$ echo $result

Oldboy

提示:这个变量可以用来判断变量是否没有定义

 

 

 

 

 

 

(2)${value:=word}  

[zgy@Web ~]$ unset result

[zgy@Web ~]$ echo $result

 

[zgy@Web ~]$ unset test

[zgy@Web ~]$ echo $test

 

[zgy@Web ~]$ result=${test:=UNSET}

[zgy@Web ~]$ echo $result

UNSET

[zgy@Web ~]$ echo $test

UNSET

[zgy@Web ~]$ test=oldboy

[zgy@Web ~]$ result=${test:=UNSET}

[zgy@Web ~]$ echo $result

oldboy

[zgy@Web ~]$ echo $test

Oldboy

提示:这个变量功能可以解决变量没有定义的问题,确保变量始终有值

 

 

 

 

 

 

 

 

(3)${value:?”word”}  

[zgy@Web ~]$ echo ${value:?"not defined"}

-bash: value: not defined

[zgy@Web ~]$ value=1

[zgy@Web ~]$ echo ${value:?"not defined"}

1

[zgy@Web ~]$ unset value

[zgy@Web ~]$ echo ${value:?"not defined"}

-bash: value: not defined

提示:用于捕捉由于未定义而导致的错误,如:"not defined"

 

 

 

 

 

(4)${var:+word}  

[zgy@Web ~]$ r=${value:+1}

[zgy@Web ~]$ echo $r

 

[zgy@Web ~]$ value=oldboy

[zgy@Web ~]$ echo $r

 

[zgy@Web ~]$ r=${value:+1}

[zgy@Web ~]$ echo $r

1

提示:此功能可用于测试变量是否存在。

 

 

(5){value:-word}去掉冒号

[zgy@Web ~]$ httpd=${HTTPD-/usr/sbin/httpd}

[zgy@Web ~]$ pidfile=${PIDFILE-/var/run/httpd,pid}

[zgy@Web ~]$ echo $httpd $pidfile

/usr/sbin/httpd /var/run/httpd,pid

[zgy@Web ~]$ echo $HTTPD $PIDFILE

 

 

 

结论:变量没定义就用-号后面的替代

 

 

 

 

(6)应用例子:/etc/init.d/httpd(注意红色部分)

apachectl=/usr/sbin/apachectl

httpd=${HTTPD-/usr/sbin/httpd}

prog=httpd

pidfile=${PIDFILE-/var/run/httpd/httpd.pid}

lockfile=${LOCKFILE-/var/lock/subsys/httpd}

RETVAL=0

 

 

 

提示:用yum安装的httpd

系统服务crond脚本使用案例:/etc/init.d/crond

 

如图:

 

 

(2)${value:=word}

与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将word赋值给value

[root@Web ~]# OLD=${value:=word}

[root@Web ~]# echo $OLD

word

[root@Web ~]# echo $value

word

[root@Web ~]# value="test"

[root@Web ~]# OLD=${value:=word}

[root@Web ~]# echo $OLD

test

[root@Web ~]# echo $value

test

 

 

注:变量替换的值也可以是``括起来的命令:$USERDIR={$Mydir:-`pwd`}

 

 

(3)${value:?message}

 若变量以赋值的话,正常替换。否则将消息message送到标准错误输出(若此替换出现在shell程序中,那么该程序将中止运行)

生产应用场景:

1)/etc/init.d/httpd

2)/etc/init.d/crond

3)对变量的路径进行操作,最好先判断路径是否为空。特别是删除操作,容易有危险。

[root@Web ~]#sed -i ‘1d’d.sh

[root@Web ~]# cat d.sh

path=/server/backup

find ${path:=/tmp/} -name “*.tar.gz” -type f | xargs rm -f

[root@Web ~]#sh -x d.sh

 

 

 

变量的处理计算变量长度与其他不同方法的耗时对比:

[root@Web ~]# chars=`seq -s " " 100`

[root@Web ~]# echo $chars

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

[root@Web ~]# echo ${#chars}

291

[root@Web ~]# echo $chars|wc -m

292

[root@Web ~]# echo $(expr length "$chars")

291

[root@Web ~]# time for i in $(seq 11111);do count=${#chars};done;

 

real 0m0.671s

user 0m0.950s

sys 0m0.002s

[root@Web ~]# time for i in $(seq 11111);do count=`echo ${chars}|wc -m`;done;

 

real 0m27.419s

user 0m1.021s

sys 0m4.189s

[root@Web ~]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;

 

real 0m6.513s

user 0m0.346s

sys 0m1.376s

 

 

  我们看到速度相差几十到上百倍,一般情况调用外部命令处理,与内置功能操作性能相差较大。在shell编程中,我们应尽量用内置操作或函数完成。

 

 

 

变量处理替换的一些参考资料

man bash变量处理大全<==学习要尽量去找一手资料

http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html

 

以上是关于十 字符串处理的主要内容,如果未能解决你的问题,请参考以下文章

片段(Java) | 机试题+算法思路+考点+代码解析 2023

●后缀数组○十三个例题

python+spark程序代码片段

一个案例说出python的十余个语法知识点

十条实用的jQuery代码片段

十 字符串处理