c语言 字符串切片重组成完整,bash脚本之一(变量+数组)

bash的变量与数组

变量:存储单个元素的内存空间; 也相当于是数组的0号索引。

数组:存储多个元素的连续的内存空间;

一、变量

1、介绍:

任何程序都需要变量。 变量是用来存储数据的。程序=指令+数据。

按照其变量是否需要严格定义其类型来划分 :

强类型语言: 简单讲就是严格区分变量类型,使用之前必须要声明一个变量的类型。如C、Python。

弱类型语言: 不强制区分变量的类型,在使用之前不用明确声明一个变量的类型,有默认的类型,一般默认是字符型的,用到时直接使用,直接赋值。 如:bash。

定义变量类型的作用:

数据存储格式;

数据的有效存储范围,有效取值范围都不一样,如 C语言的 整型,长整型。

比较机制不同,运算类型也不同。如字符 2加上3,等于 23.  而数值就是5.

不同类型的数据不能运算, 只能转换以后再运算。

变量的命令要求: 变量名其实就是指向的内存空间地址

只能使用数字、字母和下划线组成;

不能以数字开头;

不能使用程序中的关键字;

要见名知义。命名机制遵循某种法则;不能够使用程序的保留字,例如if, else, then, while等等;

2、定义变量:

本地变量:只对当前shell进程有效,对其子shell及其它shell都无效。

定义变量:[set]Var_name="Value"

引用变量:${Var_Name}

撤销变量:unset Var_Name

局部变量:仅对局部代码生效,只能在函数中使用。引用和撤销与上面相同

定义变量:local Var_Name="Value"

环境变量:对当前shell及其子shell有效,所以在当前shell中所执行的脚本也可以使用这种变量,脚本的运行环境就是子shell。

定义变量:

(1) export name=value

(2) name=value ; export name    反过来也一样。

(3) declare -x name=value

(4) name=value ; declare -x name

位置变量:用以引用执行脚本或函数时的所调用的变量。

$1,$2......$n,   对应的就是第1、2、n个参数。数字两位的时候,要用{}括起来。

#!/bin/bash

#

echo "$1 $2 $3"

star@sst-pp:/tmp$ bash test.sh user group shell

user group shell

特殊变量:

$0: 脚本名称自身。

$?: 上一条命令的执行状态。状态返回值。状态用数字来表示: 0-255;0 成功;1-255: 失败。失败状态中: 1,2(命令参数错误),127(没有命令),255  是预留的。 我们可以手动定义其它的。

$$   当前shell的PID

$!

$#   参数的数量

$*   所有参数

$@   所有参数

bash内嵌的环境变量(通常为全大写字符):用于定义bash的工作环境如:PATH, HISTFILE, HISTSIZE, HISTFILESIZE, HISTCONTROL, SHELL, HOME, UID, PWD, OLDPWD.....

查看环境变量:export, declare -x, printenv, env

撤销环境变量:unset name

只读变量:

定义变量:

declare -r name

readonly name

只读变量无法重新赋值,并且不支持撤销;存活时间为当前shell进程的生命周期,随shell进程终止而终止;

3、字符串变量修改:

只是输出,不是修改变量的值。通常用于赋值的时候。

变量是由bash提供的,所以一些操作也都支持glob风格的通配符。

下面在普通变量上面用到的功能,在数组上大部分也都可以使用。

以前写的,不怎么样,但是稍微详细点:

http://fanqie.blog.51cto.com/9382669/1649669

下面的例子中用到的变量:

hi变量保存有"Hello World"

see变量保存有"/etc/systemd/system.conf"

字符串切片:

${var:offset:number}: 取字符串的子串, 变量:偏移数:取字符数。与数组索引一样,0表示每一个元素,只不过在变量里表示第一个字符。

echo ${hi:3:2}            值:lo   从第四个字符开始,取2个。

切片也支持负数,取字符串的最右侧的几个字符:${var:  -length}

注意:以负数取值,冒号后必须有一个空白字符;如:${arr: -8} 显示后面的8个字符。

echo ${hi: -2}            值:ld

也可以定义结束范围:echo ${arr:3:-9},3到-9之间的字符。3和-9只是用来标识位置的,而不是用来定义有哪些内容的,负数就是从右到左。而最终数据取值只能是从左到右。

echo ${hi:3:-2}        值:lo Wor

基于模式取子串:

${var#*word}:其中word是指定的分隔符;

功能:最短自左而右匹配,删除所有匹配到的字符。*是通配符。

echo ${hi#?e}        值:llo World

echo ${hi#*o}        值:World

echo ${hi#*o W}    值:orld

echo ${see#*/}        值:etc/systemd/system.conf

${var##*word}:其中word是指定的分隔符;

功能:最长自左而右匹配,删除所有匹配到的字符。*是通配符。

echo ${see##*/}        值:system.conf

${var%word*}:其中word是指定的分隔符;

功能:最短自右而左匹配,删除所有匹配到的字符。

echo ${see%/*}        值:/etc/systemd

这个完成了取路径的目录名,而上面的##完成了取路径基名。

${var%%word*}:其中word是指定的分隔符;

功能:最长自右而左匹配,删除所有匹配到的字符。

echo ${see%%/*}        值:

echo ${hi%%l*}        值:He

url=https://www.google.com.hk

echo ${url%%:*}        值:https

#号标识数据的首部。 %用来标识尾部。

hi变量保存有"Hello World"

查找替换:PATTERN中可以使用glob通配符;

${var/PATTERN/SUBSTI}:查找var所表示的字符串中,第一次被PATTERN所匹配到的字符串,并将其替换为SUBSTI所表示的字符串;

echo ${hi/l/L}        值:HeLlo World

echo ${hi/ll/LL}        值:HeLLo World

echo ${hi/*o/L}        值:Lrld

${var//PATTERN/SUBSTI}:查找var所表示的字符串中,所有被PATTERN所匹配到的字符串,并将其全部替换为SUBSTI所表示的字符串;

echo ${hi//l/L}        值:HeLLo WorLd

${var/#PATTERN/SUBSTI}:查找var所表示的字符串中,行首被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;比/多了限制,只能从左每一个字符开始匹配成功。

echo ${hi/#l/L}        值:Hello World

echo ${hi/#H/L}        值:Lello World

echo ${hi/#*o/L}        值:Lrld

${var/%PATTERN/SUBSTI}:查找var所表示的字符串中,行尾被PATTERN所匹配到的字符串,将其替换为SUBSTI所表示的字符串;与上面意思一样,只不过是从右到左。

查找删除:(see为/etc/systemd/system.conf)

${var/PATTERN}:删除以PATTERN为模式第一次匹配到的var字符串。这里不用替换了,下接删除。

与#不同的是,这个是定点删除,而#是范围删除。当然如果加上通配符也一样。

echo ${see/\/systemd}        值:/etc/system.conf

${var//PATERN}  删除以PATTERN为模式所有匹配到的var字符串。

${var/#PATTERN}  以左边界匹配。

${var/%PATTERN}  以右边界匹配。

字符大小写转换:

${var^^}:把var中的所有小写字符转换为大写;

${var,,}:把var中的所有大写字符转换为小写;

这个也可以用一个^或,来表示。 只转换一个字母。也可以用#或%来定义边界。

变量赋值:

${var:-VALUE}:如果var变量为空,或未设置,那么返回VALUE;否则,则返回var变量的值;

${var:=VALUE}:如果var变量为空,或未设置,那么返回VALUE,并将VALUE赋值给var变量;否则,则返回var变量的值;

${var:+VALUE}:如果var变量不空,则返回VALUE;

${var:?ERROR_INFO}:如果var为空,或未设置,那么返回ERROR_INFO为错误提示;否则,返回var值;

而VALUE不单单只能用字符,也可以用变量引用来表示数据。

变量中字符的个数:

${#var}

二、数组:

在普通变量上面用到的功能,在数组上大部分也都可以使用。

数组名:整个数组只有一个名字;

数组索引:编号从0开始;0是第一个索引。

bash-4及之后的版本开始支持"关联数组",也就是索引不是以数字表示,而是以自定义的字符串来表示。

声明数组:

declare  -a  NAME:声明索引数组;  这个不用显示的声明,赋值的同时就自动生成数组了。

declare  -A  NAME:声明关联数组;  这个需要先在赋值之前声明。

赋值方式:

一次只赋值一个元素;

ARRAY_NAME[INDEX]=value

d61ea0f1fbeceb1026570cad1fefebfb.png

只给0和5赋值了,其它索引都没有值。

一次赋值全部元素;会把上面单独定义的覆盖

383b7b12665e7d3382a03bb1e5ff424c.png

可以看到,赋值索引是0,1,2 但是原来的5的值也没有了。

只赋值特定元素;这个也会覆盖数据。

ARRAY_NAME=([0]="VAL1"  [3]="VAL4" ...)

bash支持稀疏格式的数组;就是不按顺序来的索引。

fd8f33d72faaec728ea913fccc3fcca1.png

read  -a  ARRAY_NAME

可以用read来获取输入为数组赋值。

ec268145dc84ccda5c008f13e0c8184a.png

也就只有第一种不会覆盖不同索引的数据。如:

2166aa8ce901b3c780d7451b3dbfdb49.png

数组的长度(数组中元素的个数):

${#ARRAY_NAME[*]}

echo ${#abc[*]}            5

与变量一样,只不过这里元素个数,那里是字符个数。当然也可以查看某元素的字符的个数。

echo ${#abc[1]}            3

${#ARRAY_NAME[@]}

这个与*是一样的。

引用数组中的元素:

${ARRAY_NAME[INDEX]}

注意:引用时如果只给数组名,表示引用下标为0的元素;

引用数组中的所有元素:

${ARRAY_NAME[*]}

${ARRAY_NAME[@]}

数组元素切片:

${ARRAY_NAME[@]:offset:number}

offset:偏移的元素个数;

number:要取出的元素个数;省略number时,表示取偏移量之后的所有元素;

${arry[*]:3:2}

加上*来输出所有数据,再由3和2来定位哪个位置

如果不加*,数据只是一个字符块,会当做变量来操作。

变量也可以这样偏移,而且个数部分还可以用负数。我们上面变量部分已经试过了。

字符大小写转换

${ARRAY_NAME[*]^^}:把数组中的所有元素转换为大写;

5c60561e05f1cded6b030cd1a2862cd3.png

${ARRAY_NAME[0]^^}:把数组中的0索引元素转换为大写;

969375c06be50f3ce2ebee8d0b49de6c.png

也可以用一个^或,来表示只给首字母变化。

92bff2cc09d63c7d50b74067b805c239.png

追加元素:

因为索引是从0开始,正好与个数少1。所以只要计算出元素个数,给个数赋值即可。

只能是非稀疏格式的数组,因为索引没有规律,可能有的索引比元素个数还要大。

ARRAY_NAME[${#ARRAY_NAME[*]}]=

红色部分是用来取出数组元素的个数。

7b3ef011e1314dd6aded716ad455cf70.png

删除数组中的某元素:

unset  ARRAY[INDEX]

0d2f359bf1a9e8f6ba206696e8ca226c.png

unset ARRAY            删除数组

71057ec2e2f4640fb174330818440d28.png

关联数组:

declare  -A  ARRAY_NAME

ARRAY_NAME=([index_name1]="value1"  [index_name2]="value2" ...)

index_name就是自定义的字符串,它来做为索引,或许称为键。赋值方式与索引数组也没有什么不同。

f3a69acba27a771d3fa4ac867cd20819.png

b691348d430c82d01446de3585371e01.png

谢谢浏览。9ec2012b2f5a6483a242fc62675e6101.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值