1. 程式人生 > >shell編程進階之數組

shell編程進階之數組

shell 數組 declare eval

數組ARRAY

變量:存儲單個元素的內存空間

數組:存儲多個元素的連續的內存空間,相當於多個變量的集合,元素編號支持稀疏格式,即索引編號不連續。

高級變量用法 - 有類型變量

Shell變量一般是無類型的,但是bash提供了declare和typeset兩個命令用於指定變量的類型,兩個命令是等價的

declare [OPTION] 變量名

-r 聲明或顯示只讀變量

-i 聲明或顯示整數型變量

-a 聲明或顯示索引數組

-A 聲明或顯示關聯數組

-f 顯示系統的所有函數

-F 僅顯示所有函數名

-x 聲明或顯示環境變量和函數

-l 聲明變量為小寫字母 declare –l var=UPPER

-u 聲明變量為大寫字母 declare –u var=lower


聲明數組:

declare -a ARRAY_NAME //聲明索引數組,元素編號只能是數字,從0開始

declare -A ARRAY_NAME //聲明關聯數組,元素編號可以自定義格式,需bash4.0以上的版本才支持

declare -i ARRAY_NAME //聲明整數數組,元素變量只支持整數值

declare -r ARRAY_NAME //聲明只讀數組

declare -l ARRAY_NAME //轉換數組為小寫

declare -u ARRAY_NAME //轉換數組為大寫

聲明數組

declare -a user //聲明索引數組

declare -a //查看索引數組

declare -A user //聲明關聯數組

declare -A

declare -i //查看所有整數數組

數組元素賦值,索引數組的編號只支持數字,而且是從0開始

1.單個元素賦值

user[0]="user0"

user[1]="user1"

user[2]="user2"

user[3]="user3"

user[4]="user4"

user[5]="user5"

2.多個元素賦值

user=("usera" "userb" "userc" "userd" ...)

3.只賦值特定元素,則其他未賦值的元素值為空,如user[1]就為空

user=([0]="usera" [3]="userc"...)

4.交互式賦值

read -a user

a b c d e //輸入的參數以空格隔開

a\ b cc ee //如果輸入的參數包含空格則需要轉義,如"a b".

顯示或引用數組

declare -a

echo $user //顯示第一個元素,相當於echo ${user[0]}

echo ${user[0]}

echo ${user[2]}

echo ${user[3]}

echo ${user[*]}

echo ${#user[*]}

取消數組或元素

unset user[2] //取消數組元素2

unset user //取消整個數組


聲明關聯數組

declare -A user

數組元素賦值,編號支持字母,數字或單詞

user[a]=usera

user[b]=userb

user[2]=userc

user[abc]=userabc

查看數組元素值

declare -A|tail -1

echo ${user[a]}

echo ${user[2]}

echo ${user[abc]}

取消數組或元素

unset user[a]

unset user

批量定義數組元素,未聲明數組類型則默認為索引數組

user=(usera userb userc userd)

echo ${user[3]}

num=({1..10})

echo ${num[8]}

echo ${num[*]} //顯示數組中的所有元素,[email protected]

echo ${#num[*]} //顯示數組的元素個數,[email protected]

file=({/app/bin/*.sh})

echo ${file[3]}

echo ${file[@]} //顯示數組的所有元素

echo ${#file[@]} //顯示數組的元素個數

num=({1..10})

for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done

unset num[2]

for((i=0;i<${#num[@]};i++));do echo num is ${num[$i]};done //稀疏數組顯示會有問題,即不會自動遞歸填補空值

num[2]=3 //添加缺少的數組元素

數組元素處理

數組切片:${ARRAY[@]:offset:number}

offset: 要跳過的元素個數

number: 要取出的元素個數

num=({1..10})

echo ${num[*]:2:5} //跳過前2個,取出5個元素

3 4 5 6 7

echo ${num[*]:3} //跳過前3個,取出之後的所有元素

4 5 6 7 8 9 10 11 12 13

seq 10 //顯示1..10,默認從1開始到指定數字

seq 2 5 //顯示2,3,4,5,顯示從起始值到結束值之間的數字

seq 1 2 10 //顯示1,3,5,7,9,格式為起始值,增量值,結束值

num=10;seq 0 2 $[$num-1]

echo {1..10..2} //顯示1,3,5,7,9,格式為起始值,結束值,增量值

num=({1..10..2})

向數組中追加元素:ARRAY[${#ARRAY[*]}]

num=({1..10})

echo ${sum[10]} 值為空

num[${#num[*]}]=11 //追加數組元素,追加到所有數組元素的最後

echo ${sum[10]} 顯示追加的元素值11

num[${#num[*]}]=12 //可追加多次

num[${#num[*]}]=13

刪除數組中的某元素,會導致稀疏格式:unset ARRAY[INDEX]

unset num[8]

刪除整個數組:unset ARRAY

unset num

字符串處理

man bash 搜索\$\{parameter\} //查看命令幫助

取字符值

註意:取值時,正數前面不需要加空格,負數前面需要加一個空格。

$alp 或${alp} 顯示字符串內容

${#var} 顯示字符串的長度

${var:offset:0} 顯示所有字符串

${var:offset} 跳過前幾個字符,取後面的所有字符

${var:offset:length} 跳過前offset個字符,取其後面的length個字符

${var:offset:-length} 跳過前offset個字符和後length個字符,顯示中間的內容

${var: -length} 取字符串的最右側幾個字符。註意:冒號後有一個空格,如${num: -3}

${var: -length: -offset} 取出字符串的最右側幾個字符,然後在此基礎上,跳過後幾個字符,顯示剩余字符。

${var: -length:length} 取出字符串的最右側的幾個字符,然後在此基礎上,取出length個字符

alp=`echo {a..z}|tr -d " "` //顯示字符串abcdefg..xyz

echo $alp //顯示字符串

echo ${#alp} //查看字符串的長度,即字符個數

echo ${alp:0} //顯示所有字符串

echo ${alp:3} //跳過前3個字符,顯示後面所有字符

echo ${alp:3:5} //跳過前3個字符,取其後面的5個字符,顯示defgh

echo ${alp:3:-5} //跳過前3個字符和後5個字符,顯示中間的內容

echo ${alp: -3} //顯示最後3個字符,即xyz

echo ${alp: -3: -2} //先取出最右側的3個字符,然後再跳過後2個字符,即最後顯示字符x。

echo ${alp: -3:2} //先取出最右側的3個字符,然後取出前2個字符,即顯示為xy

刪除字符

${var#word} //刪除指定的前綴字符

${var#*word} //從左往右,匹配刪除word本身及word之前的所有字符

${var##*word} //貪婪模式,匹配刪除最後的word本身及之前的所有字符

${var%word} //刪除指定的後綴字符

${var%word*} //從右往左,匹配刪除word本身及word之後的所有字符。註意寫法*號在word右邊

${var%%word*} //貪婪模式,匹配刪除最後的word本身及之後的所有字符

url=http://www.baidu.com:80

echo ${url#http://}

echo ${url#*:}

echo ${url##*:} //取端口號

echo ${url%:80}

echo ${url%:*} //取網址

echo ${url%%:*} //取協議

取路徑和文件名

file="/var/log/messages"

echo ${file#*/} //取相對路徑:var/log/messages

echo ${file##*/} //取文件名:messages,相當於basename

echo ${file%/*} //取父目錄:/var/log,相當於dirname

查找替換

${var/pattern/string} //查找並替換第一次被匹配到的字符

${var//pattern/string} //查找並替換所有被匹配到的字符

${var/#pattern/string} //查找並替換行首匹配到的字符

${var/%pattern/string} //查找並替換行尾匹配到的字符

a=abcabc

echo ${a/b/g} //匹配替換一次,顯示為agcabc

echo ${a//a/g} //匹配替換所有,顯示為gbcgbc

echo ${a/#a/g} //匹配替換行首,顯示為gbcabc

echo ${a/%c/g} //匹配替換行尾,顯示為abcabg

url=http://www.baidu.com:80

echo ${url/%80/8080} //替換端口為8080

查找刪除

${var/pattern} //查找並刪除第一次匹配到的字符

${var//pattern} //查找並刪除所有匹配到的字符

${var/#pattern} //查找並刪除行首匹配到的字符

${var/%pattern} //查找並刪除行尾匹配到的字符

a=abcabc

echo ${a/b} //顯示為acabc

echo ${a//b} //acac

echo ${a/#a} //bcabc

echo ${a/%c} //abcab

轉換大小寫

${var^} //轉換首字母為大寫

${var^^} //把所有小寫字母轉換為大寫

${var,} //轉換首字母為小寫

${var,,} //把所有大寫字母轉換為小寫

a=abcabc

b=ABCABC

echo ${a^^} //小寫轉大寫

echo ${b,,} //大寫轉小寫

變量賦值檢測

${var:-word} 如果var值為空或未設置,則返回word值,否則返回之前設置的var值

${var:+word} 如果var值為空或未設置,則返回為空,否則返回word值

${var:=word} 如果var值為空或未設置,則設置var值為word值,即定義變量值,否則返回之前設置的var值

${var:?word} 如果var值為空或未設置,則返回錯誤信息word,否則返回之前設置的var值

a=abc

b=

echo ${a:-c} 顯示abc

echo ${b:-c} 顯示c

echo ${a:+c} 顯示c

echo ${b:+c} 顯示為空

echo ${a:=c} 顯示為abc

echo ${b:=c} 顯示為c,並賦值給b

echo $b 顯示為c,即上述賦值生效

unset b

echo ${a:?c} 或 echo ${a:?} 顯示abc

#echo ${b:?} 未定義則默認顯示如下的錯誤信息

-bash: b: parameter null or not set

#echo ${b:?this is error} 錯誤信息顯示為自定義的語句或值

-bash: b: this is error

#echo ${b:?100}

-bash: b: 100

為所有腳本使用一個獨立的變量文件,統一所有變量,類似於獨立的函數文件

echo "name=user1" > var //將所有的變量都放到文件var中,以後的腳本都調用此變量文件即可

vi a.sh

#!/bin/bash

#a.sh

. var

echo your name is $name

執行./a.sh

eval 命令將會首先掃描命令行進行所有的置換,然後再執行該命令。該命令適用於那些一次掃描無法實現其功能的變量

cmd=whoami

# echo $cmd

whoami

# echo `$cmd`

# $cmd

# eval $cmd

echo `whoami`

eval whoami

echo `ll`

eval ll //保留源命令屬性,顯示的格式等

n=10

echo {1..$n} //無法正常顯示序列

eval echo {1..$n} //正常顯示數字序列1-10

間接變量引用

如果第一個變量的值是第二個變量的名字,從第一個變量引用第二個變量的值就稱為間接變量引用

兩種方式:eval var1=\$$var2 或 var1=${!var2}

a=b

b=c

eval echo \$$a //顯示為c

echo ${!a} //顯示為c

本文出自 “rackie” 博客,請務必保留此出處http://rackie386.blog.51cto.com/11279229/1945723

shell編程進階之數組