在日常运维工作中,经常会碰到需要在一个字符串中截取我们需要的某些字符的需求,之前介绍了Shell脚本中数组的使用方法,这里介绍下基于字符串的截取的方法。在shell中截取字符串的方法有下面集中:
${var#*/}
${var##*/}
${var%/*}
${var%%/*}
${var:start:len}
${var:start}
${var:0-start:len}
${var:0-start}

可以总结为:
********************************************
#         删除最小的匹配前缀
##       删除最大的匹配前缀
%        删除最小的匹配后缀
%%     删除最大的匹配后缀
********************************************

1)获得字符串的长度
语法:${#var}

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" length=${#str}
echo "length: [${length}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
length: [37]

2)使用 # 和 ## 获取尾部子字符串(*号在分隔符的前面,就去掉其之前的字符)
2.1) # 最小限度从前面截取word
语法:${parameter#*word} , 即截取 "第一个分隔符word及其之前的字符全部删掉"后的字符

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #分割符为'/'
substr=${str#*/}
echo "substr: [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr: [/www.kevin.com/shibo/anhuigrace]

2.2)## 最大限度从前面截取word
语法:${parameter##*word},即截取 "最后一个分隔符word及其之前的字符全部删掉"后的字符

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #分割符为'/'
substr=${str##*/}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [anhuigrace]

3)使用 % 和 %% 获取头部子字符串 (*在分隔符的后面,就去掉其之后的字符)
3.1)% 最小限度从后面截取word
语法:${parameter%word*},即截取 "最后一个分隔符word及其之后的字符全部删掉"后的字符

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" substr=${str%/*}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [http://www.kevin.com/shibo]

3.2)%% 最大限度从后面截取word
语法:${parameter%%*word},即截取 "第一个分隔符word及其之后的字符全部删掉"后的字符

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" substr=${str%%/*}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [http:]

4)使用 ${var:} 模式获取子字符串
4.1)指定从左边第几个字符开始以及子串中字符的个数
语法:${var:start:len}

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #其中的 0 表示左边第一个字符开始,7 表示子字符的总个数。
substr=${str:0:7}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [http://]

4.2)从左边第几个字符开始一直到结束
语法:${var:7}

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #其中的7表示左边第8个字符开始 (如果是${str:7:5},就表示从左边第8个字符开始截取,截取5个字符)
substr=${str:7}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [www.kevin.com/shibo/anhuigrace]

4.3)从右边第几个字符开始以及字符的个数
语法:${var:0-start:len};即${var:0-8,3} 和 ${var:2-10:3} 和 ${var:5:13:3} 是一样的,即从右边第8个开始截取,截取3个字符。 即8-0=10-2=13-5=8

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #其中的 0-23 表示右边算起第23个字符开始,5 表示字符的个数
substr=${str:0-23:5}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [in.co]

4.4)从右边第几个字符开始一直到结束
语法:${var:0-start}

[root@kevin~]# cat test.sh
#!/bin/bash
str="http://www.kevin.com/shibo/anhuigrace"
echo "string: [${str}]" #其中的 0-6 表示右边算起第6个字符开始
substr=${str:0-6}
echo "substr : [${substr}]" 执行结果为:
[root@kevin~]# sh test.sh
string: [http://www.kevin.com/shibo/anhuigrace]
substr : [igrace]

####################  $( ) ${ }$(( ))的用法区别  ####################

一、$( ) 与 ` ` (反引号)
########################################################################################################################
在Shell 中,$( ) 与 ` ` (反引号) 都是用来做命令替换用的。
命令替换:就是完成()或反引号里的命令行,然后将其结果替换出来,再重组命令行。 例如:
[root@ss-server ~]# echo "this is $(date +%Y-%m-%d)"
this is 2020-01-08
[root@ss-server ~]# echo "this is `date +%Y-%m-%d`"
this is 2020-01-08 ###### 使用 $( ) 的理由 ######
1)` ` 反引号很容易与 ' ' 单引号搞混乱;
2)在多层次的复合替换中,` `反引号须要额外的跳脱( \` )处理,而 $( ) 则比较直观; 比如命令:command1 `command2 `command3` `
原本的意图:
是要在 command2 `command3` 中先将 command3 提换出来给 command 2 处理,然后再将结果传给 command1 `command2 …` 来处理。
然而,真正的结果:
在命令行中却是分成了 `command2 ` 与 ''两段。 小示例:
使用多层次的``反引号
[root@ss-server ~]# echo `echo `date +%Y-%m-%d``
date +%Y-%m-%d 换成 $( ) 就没问题了,做多少层的替换都没问题!
[root@ss-server ~]# echo $(echo $(date +%Y-%m-%d))
2020-01-08 ###### $( ) 的不足 ######
$( ) 并不见的每一种 shell类型都能使用,如果使用 bash2 的话,肯定没问题。 二、${ } 用来作变量替换
########################################################################################################################
一般情况下,$var 与 ${var} 并没有什么不一样。但是用 ${ } 会比较精确的界定变量名称的范围! 如下:
[root@ss-server ~]# a=b
[root@ss-server ~]# echo $ab [root@ss-server ~]# echo ${a}b
bb 原本是打算先将 $a 的结果替换出来,然后再补一个 b 字母于其后,
但在命令行上,真正的结果却是只会提换变量名称为 ab 的值出来,结果没有ab的变量,结果就为空了!
若使用 ${ } 就没问题。 再注意区分下面的情况:即设置变量,以 = 左边的为变量名,如以右边为变量名则无效!
[root@ss-server ~]# a=b
[root@ss-server ~]# echo ${b} [root@ss-server ~]# echo ${a}
b
[root@ss-server ~]# echo $a b
b b
[root@ss-server ~]# echo ${a}${b}
b
[root@ss-server ~]# echo ${a}${a}
bb
[root@ss-server ~]# echo ${b}${b} [root@ss-server ~]# ######################################################################
下面开始介绍下${ } 的一些高阶功能 先定义一个变量,下面示例都是以给变量做说明:
[root@ss-server ~]# file=/dir1/dir2/dir3/my.file.txt 1)可以用 ${ } 分别替换获得不同的值 ---------------------------
使用#和%进行截取字符串的方法在文章上面已经详细介绍了,这里就不做过多说明了。 ${file#*/}: 表示删除掉第一条 / 及其左边的字符串,即结果为:dir1/dir2/dir3/my.file.txt
${file##*/}: 表示删除掉最后一条 / 及其左边的字符串,即结果为:my.file.txt
${file#*.}: 表示删除掉第一个 . 及其左边的字符串,即结果为:file.txt
${file##*.}: 表示删除掉最后一个 . 及其左边的字符串,即结果为:txt
${file%/*}: 表示删除掉最后一条 / 及其右边的字符串,即结果为:/dir1/dir2/dir3
${file%%/*}: 表示删除掉第一条 / 及其右边的字符串,即结果为:(空值)
${file%.*}: 表示删除掉最后一个 . 及其右边的字符串,即结果为:/dir1/dir2/dir3/my.file
${file%%.*}: 表示删除掉第一个 . 及其右边的字符串,即结果为:/dir1/dir2/dir3/my 关于上面使用 # 和 % 的记忆方法为:
# 是删除掉指定字符串左边的!
% 是删除掉指定字符串右边的! 单一符号是最小匹配﹔两个符号是最大匹配
#*str 是删除掉第一个str及其左边的内容; ##*str 是删除掉最后一个str及其左边的内容;
%str* 是删除掉最后一个str及其右边的内容;%%str* 是删除掉第一个str及其右边的内容! 下面的截图字符串的方法在文章上面已经详细介绍了,这里就不做过多说明了。
${file:0:5}: 表示提取最左边的5个字节,即结果为:/dir1
${file:5:10}: 表示提取第5个字节右边的连续10个字节,即结果为:/dir2/dir3 如下脚本示例:
[root@bzacbsc01ap2001 ~]# hostname
bzacbsc01ap2001 主机名中第3到第6字符是本机的业务模块名称,也就是cbs。下面脚本中的表示从a字符串左边的第4个字符开始截取,截取3个字符(即3:3)
[root@bzacbsc01ap2001 ~]# cat test.sh
#!/bin/bash
a=$(hostname)
b=${a:3:3}
APP=$(echo ${b}) echo "本机tomcat的安装目录为: /opt/${APP}/tomcat" 执行结果为:
[root@bzacbsc01ap2001 ~]# sh test.sh
本机tomcat的安装目录为: /opt/cbs/tomcat 2)可以使用 ${ } 对变量值里的字符串作替换 ---------------------------
${file/dir/path}: 表示将第一个 dir 提换为 path,即结果为:/path1/dir2/dir3/my.file.txt
${file//dir/path}:表示将全部 dir 提换为 path,即结果为:/path1/path2/path3/my.file.txt 如下示例:
[root@ss-server ~]# Test_Name=kevin/bo/AnHui
[root@ss-server ~]# Test_Path=${Test_Name////.} #使用//将变量中所有的/替换为.
[root@ss-server ~]# echo ${Test_Path}
kevin.bo.AnHui
[root@ss-server ~]# Test_Path=${Test_Path/.//} #使用/将变量中第一个.替换为/
[root@ss-server ~]# echo ${Test_Path}
kevin/bo.AnHui
[root@ss-server ~]# Test_Path=$(echo $Test_Path | tr '[A-Z]' '[a-z]')
[root@ss-server ~]# echo ${Test_Path}
kevin/bo.anhui 可以在shell脚本中进行变量的多次替换,如下:
[root@ss-server ~]# vim test.sh
#!/bin/bash
MODULE_NAME=$1
.........
# image信息
IMAGE_PATH=${MODULE_NAME////.}
IMAGE_PATH=${IMAGE_PATH/.//}
IMAGE_PATH="$IMAGE_PATH.$BRANCH.$SERVICE_NAME"
IMAGE_PATH=$(echo $IMAGE_PATH | tr '[A-Z]' '[a-z]')
TAG=${REVISION:0:7}
......... 3)使用 ${ } 还可以针对不同的变量状态赋值 (没设定、空值、非空值) ---------------------------
${file-my.file.txt}: 表示假如 $file 没有设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理)
${file:-my.file.txt}: 表示假如 $file 没有设定或为空值,则使用 my.file.txt 作传回值。 (非空值时不作处理)
${file+my.file.txt}: 表示假如 $file 设为空值或非空值,均使用 my.file.txt 作传回值。(没设定时不作处理)
${file:+my.file.txt}: 表示假如 $file 为非空值,则使用 my.file.txt 作传回值。 (没设定及空值时不作处理)
${file=my.file.txt}: 表示假如 $file 没设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。 (空值及非空值时不作处理)
${file:=my.file.txt}: 表示假如 $file 没设定或为空值,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。 (非空值时不作处理)
${file?my.file.txt}: 表示假如 $file 没设定,则将 my.file.txt 输出至 STDERR。 (空值及非空值时不作处理)
${file:?my.file.txt}: 表示假如 $file 没设定或为空值,则将 my.file.txt 输出至 STDERR。 (非空值时不作处理) ${1:-NULL} 表示是当$1为空时,自动将NULL替换成$1所要带入的变量值。
${2:-NULL} 表示是当$2为空时,自动将NULL替换成$2所要带入的变量值。 例如:
[root@ss-server ~]# kevin=123
[root@ss-server ~]# echo ${kevin+anhui}
anhui [root@ss-server ~]# echo ${haha:=null} #haha变量没有设定,则使用=后面的null作为传回值
null 也可以在shell脚本中进行变量的状态赋值
[root@ss-server ~]# vim test.sh
#!/bin/bash
.........
AFS_ENV=${AFS_ENV:=null}
AFS_APPID=${AFS_APPID:=null}
AFS_CLUSTER=${AFS_CLUSTER:=null}
AFS_JARNAME=${AFS_JARNAME:=null}
......... 对于上面的理解,在于一定要分清楚 unset 与 null 及 non-null 这三种赋值状态。
一般而言, : 与 null 有关, 若不带 : 的话, null 不受影响, 若带 : 则连 null 也受影响!
[root@ss-server ~]# kevin=123
[root@ss-server ~]# echo ${kevin:+anhui}
anhui
[root@ss-server ~]# kevin=
[root@ss-server ~]# echo ${kevin:+anhui} [root@ss-server ~]# unset kevin
[root@ss-server ~]# echo ${kevin:+anhui} [root@ss-server ~]# 使用${#var}可以计算出变量的长度
[root@ss-server ~]# echo ${file}
/dir1/dir2/dir3/my.file.txt
[root@ss-server ~]# echo ${#file}
27 三、bash的组数(array)处理方法
########################################################################################################################
一般而言,A="be sh se cho" 这样的变量只是将 $A 替换为一个单一的字符串,
但是改为 A=(be sh se cho) ,则是将 $A 定义为组数,所以说数组定义需要使用()括号!! 关于数组的使用,之前已经在 https://www.cnblogs.com/kevingrace/p/5761975.html 这篇文章中详细介绍了,这里简略说下: 组数常用的几个替换方法:
${A[@]} 或 ${A[*]} 表示获得全部组数,即得到be sh se cho 。
${A[0]} 表示获得数组中的第1个组数。同理,${A[1]} 获得的是第2个组数。
${#A[@]} 或 ${#A[*]} 表示获得全部组数数量。
${#A[0]} 表示获得第一个组数的长度,即be的长度,为2; 同理,${#A[3]} 表示获得第四个组数的长度,即cho的长度,为3;
A[1]=haha 表示将第2个组数重新定义为haha; 同理,A[3]=heihei 表示将第4个组数重新定义为heihei; 四、$(( )) 用途:用来作整数运算
########################################################################################################################
在 bash 中,$(( )) 的整数运算符号大致有这些:
+ - * / 分别表示为 "加、减、乘、除"。
% 表示余数运算
& | ^ ! 分别表示分别为 "AND、OR、XOR、NOT" 运算。 例如:
[root@ss-server ~]# a=6;b=7;c=8
[root@ss-server ~]# echo $(( a+b*c ))
62
[root@ss-server ~]# echo $(( (a+b+3)/c ))
2
[root@ss-server ~]# echo $(( (a*b)%c))
2 使用$[]、let、$(()) 都可以作为整数运算,效果是一样的!
[root@ss-server ~]# echo $((4*9))
36
[root@ss-server ~]# echo $[4*9]
36
[root@ss-server ~]# let a=4*9
[root@ss-server ~]# echo $a
36
[root@ss-server ~]# let "a=4*9"
[root@ss-server ~]# echo $a
36
[root@ss-server ~]# let a="3+5"
[root@ss-server ~]# echo $a
8
[root@ss-server ~]# a=18
[root@ss-server ~]# let a++
[root@ss-server ~]# echo $a
19 事实上,单纯用 (( )) 也可重定义变量值。
(( )) 这组符号的作用与 let 指令相似,用在算数运算上,是 bash 的内建功能。所以,在执行效率上会比使用 let指令要好许多。
[root@ss-server ~]# a=10; ((a++))
[root@ss-server ~]# echo ${a}
11 [root@ss-server ~]# cat test.sh
#!/bin/bash
(( a = 10 ))
echo -e "inital value, a = $a\n" (( a++))
echo "after a++, a = $a" [root@ss-server ~]# sh test.sh
inital value, a = 10 after a++, a = 11 更多内容,可参考另一篇文章的总结: https://www.cnblogs.com/kevingrace/p/5896386.html

系统重启后DNS地址默认修改修改引起的一次事故(Tomcat报错:java.net.UnknownHostException)的更多相关文章

  1. CentOS6重启后DNS被还原的解决办法

    CentOS6重启后DNS被还原的解决办法 http://luyx30.blog.51cto.com/1029851/1070765/ centos6.5的64位系统,修改完/etc/sysconfi ...

  2. Debian8.1 安装samba与windows共享文件,在系统重启后samba服务无法自动启动

    Debian8.1安装配置完成并成功与window共享文件后,系统重启后再次访问时出现如下问题 (图)的解决方法 手动重启samba sudo /etc/init.d/samba start 从win ...

  3. ovs2.7 在系统重启后,再次使用时提示数据库无法连接的问题。

    问题现象如下,ovs开始安装后,对ovs的操作是正常的,但是,现在系统重启后,OVS的操作第一条命令就失败,如下: 问题解决方法: 参考  http://blog.csdn.net/xyq54/art ...

  4. 系统重启后,mr程序不生成当前时间段的MRx文件问题

    系统重启后,mr程序不生成当前时间段的MRx文件问题 2019-4-2 之前使用正常的MR程序,系统重启后无法生成MRE\MRO\MRS文件. 服务器有两个时钟:硬件时钟和系统时钟 硬件时钟从根本上讲 ...

  5. windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决

    windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决 一.发现问题 由于tomcat内存溢出,在wind ...

  6. 完美解决JavaIO流报错 java.io.FileNotFoundException: F:\ (系统找不到指定的路径。)

    完美解决JavaIO流报错 java.io.FileNotFoundException: F:\ (系统找不到指定的路径.) 错误原因 读出文件的路径需要有被拷贝的文件名,否则无法解析地址 源代码(用 ...

  7. Eclipse启动Tomcat报错,系统缺少本地apr库

    Eclipse启动Tomcat报错,系统缺少本地apr库. Tomcat中service.xml中的设置情况. 默认情况是HTTP协议的值:protocol="HTTP/1.1" ...

  8. 开着idea,死机了,关机重启。重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification

    开着idea,死机了,关机重启.重启之后,重新打开idea报错java.lang.AssertionError:upexpected content storage modification. goo ...

  9. 解决win7系统重启后ip丢失问题,即每次电脑重启都要重新设置ip地址,重启后ip地址没了

    自己制作的Ghost盘上网有点问题,每次重启后电脑的ip地址被还原,要重新设置 百度后终于找解决办法,在此记录. 第一步:点击左下角的WIN图标,输入CMD然后回车,打开DOS模式窗口. 第二步:在D ...

随机推荐

  1. WindowsErrorCode

    0 操作成功完成.1 功能错误.2 系统找不到指定的文件.3 系统找不到指定的路径.4 系统无法打开文件.5 拒绝访问.6 句柄无效.7 存储控制块被损坏.8 存储空间不足, 无法处理此命令.9 存储 ...

  2. cmder个人配置文件,做个记录

    以下附件是自己的cmder配置文件: https://app.yinxiang.com/shard/s13/res/30e84035-5f0f-4baf-b18c-a84ce45ec8b9/wkkcm ...

  3. RTX服务端用户数据迁移说明

    步骤一 最好在没有人使用RTX腾讯通的时候,这样你才能保证数据的实时同步;可以在服务器里面把RTX的相关服务器暂停再执行. 步骤二 进入RTX管理器用户数据----导出用户数据---还要把用户照片文件 ...

  4. switch语句(初学者)

    C语言提供了另一种用于多分支选择的switch语句(常用于开关),一般形式为: switch ( 常量表达式 ) { case 常量1 :语句; case 常量2 :语句; case 常量3 :语句; ...

  5. scanf函数(初学者)

    scanf函数称为格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中. 1.scanf函数的一般形式:scanf函数是一个标准的库函数,它的函数原型在头文件“stdio.h”中,与pr ...

  6. apply 和call 的区别,apply实用小技巧

    Js apply方法详解 我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这 ...

  7. 团队Alpha博客链接目录

    Dipper团队Alpha博客链接目录 团队Alpha冲刺博客 第一次冲刺 第二次冲刺 第三次冲刺 第四次冲刺 第五次冲刺 第六次冲刺 第七次冲刺 第八次冲刺 第九次冲刺 第十次冲刺 第十一次冲刺 第 ...

  8. vue文件在编辑器Sublime Text3中高亮

    编写代码时,代码在编辑器中显示高亮,一方面,在感官方面使人觉得很舒服:另一方面,还可以提高开发效率.下面简单介绍vue文件在Sublime Text3 中高亮的vue插件的安装方法: 第一步:安装Pa ...

  9. ThinkPHP5.0 实现 app微信支付功能

    相对于之前随笔写的<ThinkPHP5.0实现app支付宝支付功能>来说,php对接app微信支付功能就相对简单的多了,最近有加我的朋友问到app微信支付,所以我把app微信支付的demo ...

  10. php递归无限级

    function getTree($data, $pId) { $tree = ''; foreach($data as $k => $v) { if($v['cate_ParentId'] = ...