Shell编程之变量的高级用法详解

变量替换

语法 说明
${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除
${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除
${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除
${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除
${变量名/旧字符串/新字符串} 变量内容符合就字符串,则第一个旧字符串会被新字符串替换
${变量名//旧字符串/新字符串} 变量内容符合就字符串,则全部的旧字符串会被新字符串替换

示例

var1="hello world hello world"
# 所谓最长和最短其实就是正则表达式中的贪婪模式和非贪婪模式

# 删除匹配规则为*lo的数据(开头最短删除)
echo ${var1#*lo}
-> world hello world

# 删除匹配规则为*lo的数据(开头最长删除)
echo ${var1##*lo}
-> world

# 删除匹配规则为hel*的数据(尾部最短删除)
echo ${var1%hel*}
->hello world 

# 删除匹配规则为hel*的数据(尾部最长删除)
echo ${var1%%hel*}
->

# 替换第一个旧字符串world为Beijing
echo ${var1/world/Beijing}
->hello Beijing hello world

# 替换第一个旧字符串world为Beijing
echo ${var1/world/Beijing}
->hello Beijing hello Beijing

变量测试

变量置换方式 变量y没有设置 变量y为空值 变量y设置值
x=${y-新值} x=新值 x为空 x=$y
x=${y:-新值} x=新值 x新值 x=$y
x=${y+新值} x为空 x=新值 x=新值
x=${y:+新值} x为空 x为空 x=新值
x=${y=新值} x=新值 x为空 x=$y
y=新值 y值不变 y值不变
x=${y:=新值} x=新值 x=新值 x=$y
y=新值 y=新值 y值不变
x=${y?新值} 新值输出到标准错误输出(屏幕) x为空 x=$y
x=${y:?新值} 新值输出到标准错误输出 新值输出到标准错误输出 x=$y
  • 如果大括号内没有":",则变量 y 为空或没有被设置,处理方法是不同的;如果大括号内有":",则变量 y
  • 不论是为空,还是没有被设置,处理方法是一样的;
  • 如果大括号内是"-“或”+",则在改变变量 x 的值的时候,变量 y 的值是不改变的;
  • 如果大括号内是"=",则在改变变量 x 的值的同时,变量 y 的值也会改变;
  • 如果大括号内是"?",则当变量 y 不存在或为空时,会把"新值"当成报错输出到屏幕上。

示例

# x=${y-新值}
echo ${y=$var1}
->hello world hello world

y=
echo ${y-$var1}
->

y=hello Beijing
echo ${y-$var1}
->hello Beijing

# x=${y:-新值}
echo ${y:-$var1}
->hello world hello world

y=
echo ${y:-$var1}
->hello world hello world

y=hello Beijing
echo ${y:-$var1}
->hello Beijing

# x=${y+新值}
echo ${y+$var1}
->

y=
echo ${y+$var1}
->hello world hello world

y=hello Beijing
echo ${y+var1}
->hello world hello world

# x=${y:+新值}
echo ${y:+$var1}
->

y=
echo ${y:+$var1}
->

y=hello Beijing
echo ${y:+var1}
->hello world hello world

# x=${y=新值}
x=${y=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=
x=${y=$var1}
echo $x
->
echo $y
->

y=hello Beijing
x=${y=$var1}
echo $x
->hello world hello world
echo $y
->hello Beijing

# x=${y:=新值}
x=${y:=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=
x=${y:=$var1}
echo $x
->hello world hello world
echo $y
->hello world hello world

y=hello Beijing
x=${y:=$var1}
echo $x
->hello Beijing
echo $y
->hello Beijing

# x=${y?新值}
echo ${y?$var1}
->-bash: y: hello world hello world

y=
echo ${y?$var1}
->

y=hello Beijing
echo ${y?$var1}
->hello Beijing

# x=${y:?新值}
echo ${y?$var1}
->-bash: y: hello world hello world

y=
echo ${y:?$var1}
->-bash: y: hello world hello world

y=hello Beijing
echo ${y:?$var1}
->hello Beijing

看完了我还是记不住!!参考上表吧!

字符串处理

字符串长度

语法 说明
方法一 ${#string}
方法二 expr length "$string" string有空格,则必须加双引号

示例

# 方法一
var1="hello world"
echo ${#var1}
->11

# 方法二
len=`expr length "$var1"`
echo $len
->11

## var1有空格,必须加双引号,否则报错
expr: syntax error

## var2没有空格,可以不需要加双引号
var2=hello
expr length $var2
5

子串字符索引

语法 expr index $string $substring string/substring有空格,则必须加双引号 此方法并不是查找子串的索引位置,它会把子串进行字符拆分,哪个字符最先找到了则返回其索引位置。并且索引从1开始
expr index "$var1" llo
->3

expr index "$var1" lole
->2

子串长度

语法 expr match $string substring string/substring有空格,则必须加双引号
expr match "$var1" hel
->3

expr match "$var1" llo
->0

expr match $string substring获取子串长度必须是从头开始匹配

抽取子串

语法 说明
方法一 ${string:position} 从string中的position开始抽取子串
方法二 ${string:position:length} 从string中的position开始,抽取长度为length的子串
方法三 ${string: -position} (注意-position前有个空格)从尾部开始的position抽取子串
方法四 ${string:(position)} 从string中的头部开始的position抽取子串
方法五 expr substr $string $position $length 从string中的position开始,抽取长度为length的子串

示例

# 方法一
echo ${var1:2}
->llo world

# 方法二
echo ${var1:2:5}
->llo w

# 方法三
echo ${var1: -2}
->ld

echo ${var1: -2:1}
->l

# 方法四
echo ${var1:(3)}
->lo world

echo ${var1:(3):2}
->lo

echo ${var1:(-2):1}
->l

# 方法五
expr substr "$var1" 2 5
->ello

注意:expr substr $string $position $length的position从1开始,而${string:position:length}的从0开始。

var2=hello
echo ${var2:2:5}
->llo

expr substr $var2 2 5
->ello

小试牛刀

需求描述:变量string="Bigdata process framework is Hadoop,Hadoop is an open source project."执行脚本后,打印输出string字符串变量,并给出用户一下选项:

  • 打印string长度
  • 删除字符串中所有的Hadoop
  • 替换第一个Hadoop为Mapreduce
  • 替换所有Hadoop为Mapreduce

用户输入数字1|2|3|4,可以执行对应项的功能;输入q|Q则退出交互模式。

#!/bin/bash

string="Bigdata process framework is Hadoop,Hadoop is an open source project."

function print_tips
{
 echo "=============================="
 echo "1->打印string长度"
 echo "2->删除字符串中所有的Hadoop"
 echo "3->替换第一个Hadoop为Mapreduce"
 echo "4->替换所有Hadoop为Mapreduce"
 echo "q|Q->退出"
 echo "=============================="
}

function len_of_string
{
 echo "${#string}"
}

function del_hadoop
{
 echo "${string//Hadoop/}"
}

function rep_first_hadoop_mapreduce
{
 echo "${string/Hadoop/Mapreduce}"
}

function rep_all_hadoop_mapreduce
{
 echo "${string//Hadoop/Mapreduce}"
}
while true
do
 echo ""
        echo ""
        echo ""
        echo ""
 echo "【string=$string】"
 print_tips
 read -p "Please input your choice (1|2|3|4|q|Q):" choice
 case $choice in
  1)len_of_string;;
  2)del_hadoop;;
  3)rep_first_hadoop_mapreduce;;
  4)rep_all_hadoop_mapreduce;;
  q|Q)exit;;
  *)echo "Error input,only in (1|2|3|4|q|Q)";;
 esac
done

命令替换

Shell 命令替换是指将命令的输出结果赋值给某个变量。比如,在某个目录中输入 ls 命令可查看当前目录中所有的文件,但如何将输出内容存入某个变量中呢?这就需要使用命令替换了,这也是 Shell 编程中使用非常频繁的功能。

语法
方法一 `command`
方法二 $(command)

示例

# 获取系统的所有用户并输出
#!/bin/bash

index=1
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
 echo "这是第 $index 个用户,名称为:$user"
 index=$(($index + 1))
        # $(())主要用来进行整数运算,引用变量前面可以加$也可以不加
done

# 根据系统时间计算今年或明年
#!/bin/bash

year=`date +%Y`
echo "今年是$year年,明年是$(($year+1))年"

# 根据系统时间获取今年还剩下多少星期,已经过了多少星期
#!/bin/bash

# 计算现在是今年第几天
#!/bin/bash

days=$(date +%j)
weeks=$((days/7))
remain_weeks=$((52-weeks))
echo "今年还剩$remain_weeks个星期,已经过了$weeks个星期"

# 判定nginx进程是否存在,若不存在则自动拉起进程
#!/bin/bash

nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ];then
 echo "nginx未启动,拉起中..."
 systemctl start nginx
else
 echo "nginx已启动..."
fi

有类型变量

在之前的变量声明中都是没有指定变量类型的,在Shell编程中如果需要为变量指定类型则需要使用declare和typeset命令。这两个命令是等价的。(下表中-号为添加,取消则使用+号,如+x)

参数 含义
-r 将变量设置为只读
-i 将变量设置为整数
-a 将变量定义为数组
-f 显示此脚本前定义过的所有函数及内容
-F 仅显示此脚本前定义过的函数名
-x 将变量声明为环境变量

示例

# 设置为只读
var1="hello wordl"
var1="hello shell"
declare -r var1
var1="hello java"
->-bash: var1: readonly variable

# 设置为整形
num1=20
num2=$num1+30
echo $num2
->20+30 #linux默认设置为字符串
declare -i num3
num3=$num1+30
echo $num3
->50

# 定义数组
declare -a array
array=(1 2 3 4)
# 输出全部内容
echo ${array[@]}
# 输出下标索引为1的内容
echo ${array[1]}
# 数组内元素个数
echo ${#array[@]}
# 指定索引赋值
array[0]=555
# 尾部添加元素
array[4]=666
# 删除元素
# 删除索引为2的元素
unset array[2]
# 清空整个数组
unset array
# 分片访问
# 显示数组下标索引从1开始到3的三个元素(包头不包尾)
${array[@]:1:4}
# 数组遍历
for n in ${array[@]}
do
    echo $n
done

# 显示脚本前定义过的所有函数及内容
# 在前问小试牛刀的print_tips方法后添加declare -f,即可发现只显示了命令前的函数及内容

数学运算之expr

expr操作符对照表:

操作符 含义
num1 | num2 num1不为空且非0,返回num1;否则返回num2
num1 & num2 num1不为空且非0,返回num1;否则返回0
num1 < num2 num1小于num2,返回1;否则返回0
num1 <= num2 num1小于等于num2,返回1;否则返回0
num1 = num2 num1等于num2,返回1;否则返回0
num1 != num2 num1不等于num2,返回1;否则返回0
num1 > num2 num1大于num2,返回1;否则返回0
num1 >= num2 num1大于等于num2,返回1;否则返回0

注意:如果需要在命令行中使用这些运算需要转义,如expr $num1 \| $num2,expr $num1 \> $num2,否则报错。

num1=20
num2=100
expr $num1 \| $num2
expr $num1 \& $num2
expr $num1 \< $num2
expr $num1 \<= $num2
expr $num1 \> $num2
expr $num1 \>= $num2
expr $num1 = $num2
expr $num1 != $num2
expr $num1 + $num2
expr $num1 - $num2
expr $num1 \* $num2
expr $num1 / $num2
expr $num1 % $num2

数学运算之bc

bc是bash内建的运算器,支持浮点数运算。默认情况下bc运算精确到整数,可以设置scale来保留指定位数的小数。

bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
23/5
4
scale=2
23/5
4.60

在shell中通常通过管道来使用bc。如:echo "2.5/3.65" | bc或echo 'scale=2; (2.777 - 1.4744)/1' | bc。注意:后者的/1操作,如果不进行除法则无法保留指定位数的小数
      bc 除了 scale 来设定小数位之外,还有 ibase(输入数据的进制) 和 obase(输出的数据进制) 来其它进制的运算。

echo "ibase=2;111" |bc
->7

echo "obase=2;192" |bc
->11000000

到此这篇关于Shell编程之变量的高级用法详解的文章就介绍到这了,更多相关Shell 变量的高级用法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详解shell 变量的高级用法示例

    变量删除和替换 案例:从头开始匹配,将符合最短的数据删除 (#) variable_1="I love you, Do you love me" echo $variable_1 variable_2=${variable_1#*ov} echo $variable_2 案例:从头开始匹配,将复合最短的数据删除(##) varible_3=${variable_1##*ov} echo $varible_3 案例:替换字符串,只替换第一次匹配成功的(/) echo $PATH var6

  • Shell编程之变量的高级用法详解

    变量替换 语法 说明 ${变量名#匹配规则} 从变量开头进行规则匹配,将符合最短的数据删除 ${变量名##匹配规则} 从变量开头进行规则匹配,将符合最长的数据删除 ${变量名%匹配规则} 从变量尾部进行规则匹配,将符合最短的数据删除 ${变量名%%匹配规则} 从变量尾部进行规则匹配,将符合最长的数据删除 ${变量名/旧字符串/新字符串} 变量内容符合就字符串,则第一个旧字符串会被新字符串替换 ${变量名//旧字符串/新字符串} 变量内容符合就字符串,则全部的旧字符串会被新字符串替换 示例 var

  • Python3网络爬虫中的requests高级用法详解

    本节我们再来了解下 Requests 的一些高级用法,如文件上传,代理设置,Cookies 设置等等. 1. 文件上传 我们知道 Reqeuests 可以模拟提交一些数据,假如有的网站需要我们上传文件,我们同样可以利用它来上传,实现非常简单,实例如下: import requests files = {'file': open('favicon.ico', 'rb')} r = requests.post('http://httpbin.org/post', files=files) print

  • python re模块的高级用法详解

    总结 以上所述是小编给大家介绍的python re模块的高级用法详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对我们网站的支持!

  • python中for循环变量作用域及用法详解

    在讲这个话题前,首先我们来看一道题: 代码1: def foo(): return [lambda x: x**i for i in range(1,5,2)] print([f(3) for f in foo()]) 伙伴们,你们认为这里产生的结果是什么呢?我们再来看下这题的变体: 代码:2 def foo(): functions=[] for i in range(1,5,2): def inside_fun(x): return x ** i functions.append(insid

  • linux shell命令行选项与参数用法详解

    问题描述:在linux shell中如何处理tail -n 10 access.log这样的命令行选项?在bash中,可以用以下三种方式来处理命令行参数,每种方式都有自己的应用场景.1,直接处理,依次对$1,$2,...,$n进行解析,分别手工处理:2,getopts来处理,单个字符选项的情况(如:-n 10 -f file.txt等选项):3,getopt,可以处理单个字符选项,也可以处理长选项long-option(如:--prefix=/home等).总结:小脚本手工处理即可,getopt

  • PHP的switch判断语句的“高级”用法详解

    只所以称为"高级"用法,是因为我连switch的最基础的用法都还没有掌握,so,接下来讲的其实还是它的基础用法! switch 语句和具有同样表达式的一系列的 IF 语句相似.很多场合下需要把同一个变量(或表达式)与很多不同的值比较,并根据它等于哪个值来执行不同的代码.这正是 switch 语句的用途. 注意: 注意和其它语言不同,continue 语句作用到 switch 上的作用类似于 break.如果在循环中有一个 switch 并希望 continue 到外层循环中的下一个轮回

  • PHP模板引擎Smarty内置变量调解器用法详解

    本文实例讲述了PHP模板引擎Smarty内置变量调解器用法.分享给大家供大家参考,具体如下: Smarty 中的变量调解器相当于函数,其调用方式为:通过 "|" 后面直接跟调解器函数名,如果有参数,得加在 ":" 后面,多个参数的话,累加即可. 下面为您介绍 Smarty 中内置的变量调解器: 1.capitalize 将变量里的所有单词首字大写.参数值 boolean 型决定带数字的单词,首字是否大写.默认不大写 index.php $tpl->assign

  • Java SpringBoot高级用法详解

    目录 1,IDEA中Lombok作用 创建项目 2.pom.xml说明 2.1 pom.xml标签说明 2.2 依赖的相关说明 2.3 SHA1介绍 SpringBoot高级用法 YML文件说明 3.需求说明 3.2利用properties文件为属性赋值 总结 1,IDEA中Lombok作用 数据库: 库 表 字段 对应的值 user表(id,name,age) 实体对象pojo: 用来封装数据库中的数据 User类(id,name,age) 实体对象方法: Get/Set/toString/无

  • Mybatis Example的高级用法详解

    目录 Mybatis Example的高级用法 一. mapper接口中的函数及方法 二. example实例方法 三. 使用案例 说说Mybatis Example常见用法 一. 说明 二. 排序查询 三. 查询limit, 只返回前50条数据 Mybatis Example的高级用法 近几个项目一直使用的mybatis来对数据库做查询,期间用到了很多高效简洁的查询方法,特此记录和分享. 一. mapper接口中的函数及方法 方法名 功能 int countByExample(UserExam

  • Python中第三方库Requests库的高级用法详解

    一.Requests库的安装 利用 pip 安装,如果你安装了pip包(一款Python包管理工具,不知道可以百度哟),或者集成环境,比如Python(x,y)或者anaconda的话,就可以直接使用pip安装Python的库. $ pip install requests 安装完成之后,下面来看一下基本的方法: #get请求方法 >>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) #打印g

随机推荐