linux数组下当前的IP地址存在哪个数组里

在上一章中,我们查看了 shell 怎样操作字符串和数字的。目前我们所见到的数据类型在计算机科学圈里被
成为标量变量;也就是说,只能包含一个值的变量。
在本章中,我们将看看另一种数据结构叫做数组,数组能存放多个值。数组几乎是所有编程语言的一个特性。
shell 也支持它们,尽管以一个相当有限的形式。即便如此,为解决编程问题,它们是非常有用的。
什么是数组?
数组是一次能存放多个数据的变量。数组的组织结构就像一张表。我们拿电子表格举例。一张电子表格就像是一个
二维数组。它既有行也有列,并且电子表格中的一个单元格,可以通过单元格所在的行和列的地址定位它的位置。
数组行为也是如此。数组有单元格,被称为元素,而且每个元素会包含数据。
使用一个称为索引或下标的地址可以访问一个单独的数组元素。
大多数编程语言支持多维数组。一个电子表格就是一个多维数组的例子,它有两个维度,宽度和高度。
许多语言支持任意维度的数组,虽然二维和三维数组可能是最常用的。
Bash 中的数组仅限制为单一维度。我们可以把它们看作是只有一列的电子表格。尽管有这种局限,但是有许多应用使用它们。
对数组的支持第一次出现在 bash 版本2中。原来的 Unix shell 程序,sh,根本就不支持数组。
创建一个数组
数组变量就像其它 bash 变量一样命名,当被访问的时候,它们会被自动地创建。这里是一个例子:
[me@linuxbox ~]$ a[1]=foo
[me@linuxbox ~]$ echo ${a[1]}
这里我们看到一个赋值并访问数组元素的例子。通过第一个命令,把数组 a 的元素1赋值为 “foo”。
第二个命令显示存储在元素1中的值。在第二个命令中使用花括号是必需的,
以便防止 shell 试图对数组元素名执行路径名展开操作。
也可以用 declare 命令创建一个数组:
[me@linuxbox ~]$ declare -a a
使用 -a 选项,declare 命令的这个例子创建了数组 a。
有两种方式可以给数组赋值。单个值赋值使用以下语法:
name[subscript]=value
这里的 name 是数组的名字,subscript 是一个大于或等于零的整数(或算术表达式)。注意数组第一个元素的下标是0,
而不是1。数组元素的值可以是一个字符串或整数。
多个值赋值使用下面的语法:
name=(value1 value2 ...)
这里的 name 是数组的名字,value... 是要按照顺序赋给数组的值,从元素0开始。例如,如果我们希望
把星期几的英文简写赋值给数组 days,我们可以这样做:
[me@linuxbox ~]$ days=(Sun Mon Tue Wed Thu Fri Sat)
还可以通过指定下标,把值赋给数组中的特定元素:
[me@linuxbox ~]$ days=([0]=Sun [1]=Mon [2]=Tue [3]=Wed [4]=Thu [5]=Fri [6]=Sat)
访问数组元素
那么数组对什么有好处呢? 就像许多数据管理任务一样,可以用电子表格程序来完成,许多编程任务则可以用数组完成。
让我们考虑一个简单的数据收集和展示的例子。我们将构建一个脚本,用来检查一个特定目录中文件的修改次数。
从这些数据中,我们的脚本将输出一张表,显示这些文件最后是在一天中的哪个小时被修改的。这样一个脚本
可以被用来确定什么时段一个系统最活跃。这个脚本,称为 hours,输出这样的结果:
[me@linuxbox ~]$ hours .
Hour Files Hour Files
---- ----- ---- ----
Total files = 80
当执行该 hours 程序时,指定当前目录作为目标目录。它打印出一张表显示一天(0-23小时)每小时内,
有多少文件做了最后修改。程序代码如下所示:
#!/bin/bash
# hours : script to count files by modification time
usage () {
echo "usage: $(basename $0) directory" &&2
# Check that argument is a directory
if [[ ! -d $1 ]]; then
# Initialize array
for i in {0..23}; do hours[i]=0; done
# Collect data
for i in $(stat -c %y "$1"/* | cut -c 12-13); do
((++hours[j]))
((++count))
# Display data
echo -e "Hour\tFiles\tHour\tFiles"
echo -e "----\t-----\t----\t-----"
for i in {0..11}; do
j=$((i + 12))
printf "%02d\t%d\t%02d\t%d\n" $i ${hours[i]} $j ${hours[j]}
printf "\nTotal files = %d\n" $count
这个脚本由一个函数(名为 usage),和一个分为四个区块的主体组成。在第一部分,我们检查是否有一个命令行参数,
且该参数为目录。如果不是目录,会显示脚本使用信息并退出。
第二部分初始化一个名为 hours 的数组。给每一个数组元素赋值一个0。虽然没有特殊需要在使用之前准备数组,但是
我们的脚本需要确保没有元素是空值。注意这个循环构建方式很有趣。通过使用花括号展开({0..23}),我们能
很容易为 for 命令产生一系列的数据(words)。
接下来的一部分收集数据,对目录中的每一个文件运行 stat 程序。我们使用 cut 命令从结果中抽取两位数字的小时字段。
在循环里面,我们需要把小时字段开头的零清除掉,因为 shell 将试图(最终会失败)把从 “00” 到 “09” 的数值解释为八进制(见表35-1)。
下一步,我们以小时为数组索引,来增加其对应的数组元素的值。最后,我们增加一个计数器的值(count),记录目录中总共的文件数目。
脚本的最后一部分显示数组中的内容。我们首先输出两行标题,然后进入一个循环产生两栏输出。最后,输出总共的文件数目。
有许多常见的数组操作。比方说删除数组,确定数组大小,排序,等等。有许多脚本应用程序。
输出整个数组的内容
下标 * 和 @ 可以被用来访问数组中的每一个元素。与位置参数一样,@ 表示法在两者之中更有用处。
这里是一个演示:
[me@linuxbox ~]$ animals=("a dog" "a cat" "a fish")
[me@linuxbox ~]$ for i in ${animals[*]}; do echo $i; done
[me@linuxbox ~]$ for i in ${animals[@]}; do echo $i; done
[me@linuxbox ~]$ for i in "${animals[*]}"; do echo $i; done
a dog a cat a fish
[me@linuxbox ~]$ for i in "${animals[@]}"; do echo $i; done
我们创建了数组 animals,并把三个含有两个字的字符串赋值给数组。然后我们执行四个循环看一下对数组内容进行分词的效果。
表示法 ${animals[*]} 和 ${animals[@]}的行为是一致的直到它们被用引号引起来。
确定数组元素个数
使用参数展开,我们能够确定数组元素的个数,与计算字符串长度的方式几乎相同。这里是一个例子:
[me@linuxbox ~]$ a[100]=foo
[me@linuxbox ~]$ echo ${#a[@]} # number of array elements
[me@linuxbox ~]$ echo ${#a[100]} # length of element 100
我们创建了数组 a,并把字符串 “foo” 赋值给数组元素100。下一步,我们使用参数展开来检查数组的长度,使用 @ 表示法。
最后,我们查看了包含字符串 “foo” 的数组元素 100 的长度。有趣的是,尽管我们把字符串赋值给数组元素100,
bash 仅仅报告数组中有一个元素。这不同于一些其它语言的行为,数组中未使用的元素(元素0-99)会初始化为空值,
并把它们计入数组长度。
找到数组使用的下标
因为 bash 允许赋值的数组下标包含 “间隔”,有时候确定哪个元素真正存在是很有用的。为做到这一点,
可以使用以下形式的参数展开:
${!array[*]}
${!array[@]}
这里的 array 是一个数组变量的名字。和其它使用符号 * 和 @ 的展开一样,用引号引起来的 @ 格式是最有用的,
因为它能展开成分离的词。
[me@linuxbox ~]$ foo=([2]=a [4]=b [6]=c)
[me@linuxbox ~]$ for i in "${foo[@]}"; do echo $i; done
[me@linuxbox ~]$ for i in "${!foo[@]}"; do echo $i; done
在数组末尾添加元素
如果我们需要在数组末尾附加数据,那么知道数组中元素的个数是没用的,因为通过 * 和 @ 表示法返回的数值不能
告诉我们使用的最大数组索引。幸运地是,shell 为我们提供了一种解决方案。通过使用 += 赋值运算符,
我们能够自动地把值附加到数组末尾。这里,我们把三个值赋给数组 foo,然后附加另外三个。
[me@linuxbox~]$ foo=(a b c)
[me@linuxbox~]$ echo ${foo[@]}
[me@linuxbox~]$ foo+=(d e f)
[me@linuxbox~]$ echo ${foo[@]}
a b c d e f
就像电子表格,经常有必要对一列数据进行排序。Shell 没有这样做的直接方法,但是通过一点儿代码,并不难实现。
#!/bin/bash
# array-sort : Sort an array
a=(f e d c b a)
echo "Original array: ${a[@]}"
a_sorted=($(for i in "${a[@]}"; do echo $i; done | sort))
echo "Sorted array: ${a_sorted[@]}"
当执行之后,脚本产生这样的结果:
[me@linuxbox ~]$ array-sort
Original array: f e d c b a
Sorted array:
a b c d e f
脚本运行成功,通过使用一个复杂的命令替换把原来的数组(a)中的内容复制到第二个数组(a_sorted)中。
通过修改管道线的设计,这个基本技巧可以用来对数组执行各种各样的操作。
删除一个数组,使用 unset 命令:
[me@linuxbox ~]$ foo=(a b c d e f)
[me@linuxbox ~]$ echo ${foo[@]}
a b c d e f
[me@linuxbox ~]$ unset foo
[me@linuxbox ~]$ echo ${foo[@]}
[me@linuxbox ~]$
也可以使用 unset 命令删除单个的数组元素:
[me@linuxbox~]$ foo=(a b c d e f)
[me@linuxbox~]$ echo ${foo[@]}
a b c d e f
[me@linuxbox~]$ unset 'foo[2]'
[me@linuxbox~]$ echo ${foo[@]}
在这个例子中,我们删除了数组中的第三个元素,下标为2。记住,数组下标开始于0,而不是1!也要注意数组元素必须
用引号引起来为的是防止 shell 执行路径名展开操作。
有趣地是,给一个数组赋空值不会清空数组内容:
[me@linuxbox ~]$ foo=(a b c d e f)
[me@linuxbox ~]$ foo=
[me@linuxbox ~]$ echo ${foo[@]}
任何引用一个不带下标的数组变量,则指的是数组元素0:
[me@linuxbox~]$ foo=(a b c d e f)
[me@linuxbox~]$ echo ${foo[@]}
a b c d e f
[me@linuxbox~]$ foo=A
[me@linuxbox~]$ echo ${foo[@]}
A b c d e f
现在最新的 bash 版本支持关联数组了。关联数组使用字符串而不是整数作为数组索引。
这种功能给出了一种有趣的新方法来管理数据。例如,我们可以创建一个叫做 “colors” 的数组,并用颜色名字作为索引。
declare -A colors
colors["red"]="#ff0000"
colors["green"]="#00ff00"
colors["blue"]="#0000ff"
不同于整数索引的数组,仅仅引用它们就能创建数组,关联数组必须用带有 -A 选项的 declare 命令创建。
访问关联数组元素的方式几乎与整数索引数组相同:
echo ${colors["blue"]}
在下一章中,我们将看一个脚本,很好地利用关联数组,生产出了一个有意思的报告。
如果我们在 bash 手册页中搜索单词 “array”的话,我们能找到许多 bash 在哪里会使用数组变量的实例。其中大部分相当晦涩难懂,
但是它们可能在一些特殊场合提供临时的工具。事实上,在 shell 编程中,整套数组规则利用率相当低,很大程度上归咎于这样的事实,
传统 Unix shell 程序(比如说 sh)缺乏对数组的支持。这样缺乏人气是不幸的,因为数组广泛应用于其它编程语言,
并为解决各种各样的编程问题,提供了一个强大的工具。
数组和循环有一种天然的姻亲关系,它们经常被一起使用。该
for (( expr))
形式的循环尤其适合计算数组下标。
Wikipedia 上面有两篇关于在本章提到的数据结构的文章:最新注册:本站是一个php程序员的工作生活笔记,本站包含了php网络编程学习教程,数据库(主要是MySQL数据库)教程,javascript,jquery,div+css,html,windows系统以及linux系统方面的学习笔记和工作经验的积累!订阅本站|周热门文章热门标签最新评论|05-0406-2810-1609-2210-1611-1801-2206-1410-0702-23随机文章04-2804-2505-1104-2705-1304-2704-2705-0704-0205-11PHP笔记04-2804-2204-2204-2202-2301-2001-2001-1701-0811-03数据库教程01-0407-0805-2403-0203-0203-0203-0201-2201-0312-27JavaScript教程04-1010-2910-1310-1110-0508-1208-1203-0209-2612-11HTML教程04-1907-0912-1612-1605-2605-2005-0504-0212-1812-03操作系统技巧05-0704-1103-2903-0102-2401-1701-0512-2112-1812-11博客访问: 475550
博文数量: 96
博客积分: 2110
博客等级: 大尉
技术积分: 1004
注册时间:
分类: LINUX 16:45:49
linux shell在编程方面比windows 批处理强大太多,无论是在循环、运算。已经数据类型方面都是不能比较的。 下面是个人在使用时候,对它在数组方面一些操作进行的总结。
1.数组定义
[chengmo@centos5 ~]$ a=(1 2 3 4 5)[chengmo@centos5 ~]$ echo $a1
一对括号表示是数组,数组元素用“空格”符号分割开。
2.数组读取与赋值
得到长度:
[chengmo@centos5 ~]$ echo ${#a[@]}5
用${#数组名[@或*]} 可以得到数组长度
[chengmo@centos5 ~]$ echo ${a[2]} 3
[chengmo@centos5 ~]$ echo ${a[*]} 1 2 3 4 5&&&
用${数组名[下标]} 下标是从0开始& 下标是:*或者@ 得到整个数组内容
[chengmo@centos5 ~]$ a[1]=100
[chengmo@centos5 ~]$ echo ${a[*]} 1 100 3 4 5
[chengmo@centos5 ~]$ a[5]=100&&&& [chengmo@centos5 ~]$ echo ${a[*]}
1 100 3 4 5 100
直接通过 数组名[下标] 就可以对其进行引用赋值,如果下标不存在,自动添加新一个数组元素
[chengmo@centos5 ~]$ a=(1 2 3 4 5)[chengmo@centos5 ~]$ unset a[chengmo@centos5 ~]$ echo ${a[*]}
[chengmo@centos5 ~]$ a=(1 2 3 4 5)[chengmo@centos5 ~]$ unset a[1]&& [chengmo@centos5 ~]$ echo ${a[*]} 1 3 4 5[chengmo@centos5 ~]$ echo ${#a[*]}4
直接通过:unset 数组[下标] 可以清除相应的元素,不带下标,清除整个数据。
3.特殊使用
[chengmo@centos5 ~]$ a=(1 2 3 4 5)[chengmo@centos5 ~]$ echo ${a[@]:0:3}1 2 3[chengmo@centos5 ~]$ echo ${a[@]:1:4}2 3 4 5
[chengmo@centos5 ~]$ c=(${a[@]:1:4})[chengmo@centos5 ~]$ echo ${#c[@]}4[chengmo@centos5 ~]$ echo ${c[*]} 2 3 4 5
直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用“空格”分开,因此如果加上”()”,将得到切片数组,上面例子:c 就是一个新数据。
[chengmo@centos5 ~]$ a=(1 2 3 4 5)&&& [chengmo@centos5 ~]$ echo ${a[@]/3/100}1 2 100 4 5[chengmo@centos5 ~]$ echo ${a[@]}1 2 3 4 5[chengmo@centos5 ~]$ a=(${a[@]/3/100}) [chengmo@centos5 ~]$ echo ${a[@]}&&&& 1 2 100 4 5
调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。
从上面讲到的,大家可以发现linux shell 的数组已经很强大了,常见的操作已经绰绰有余了。
shell 按行读取并保存成数组
从ip.txt里读取IP.然后把IP地址赋值到一个数组里.IP文件如下:Address:&&220.181.26.163Address:&&220.181.26.174Address:&&220.181.26.175Address:&&220.181.26.176Address:&&220.181.19.228Address:&&220.181.19.229Address:&&220.181.26.161Address:&&220.181.26.162
方法一:for x in ` awk '{print $2}' ip.txt `{echo $x}方法二:ARRAY=($(awk '{print $2}' ip.txt))方法三:n=0;do array[$n]=$b;((n++));done<ip.txt
方法四:n=1while ((n<=$(cat ip.txt|wc -l)))do&&& ipaddr[$n]=$(cat ip.txt|sed -n "${n}p"|awk '{print $2}')&&& ((n+=1))donen=`expr $n - 1`
数组实用示例
1、从“标准输入”读入n次字符串,每次输入的字符串保存在数组array里
i=0n=5while [ "$i" -lt $n ] ; do& echo "Please input strings ... `expr $i + 1`"& read array[$i]& b=${array[$i]}& echo "$b"& i=`expr $i + 1`done
2、将字符串里的字母逐个放入数组,并输出到“标准输出”chars='abcdefghijklmnopqrstuvwxyz'for (( i=0; i<26; i++ )) ; do&&& array[$i]=${chars:$i:1}&&& echo ${array[$i]}done
这里有趣的地方是 ${chars:$i:1},表示从chars字符串的 $i 位置开始,获取 1 个字符。如果将 1 改为 3 ,就获取 3 个字符啦~ 结果是:
abcbcd...vxyxyzyz&&&& //没有足够字符串获取了z&&&&& //没有足够字符串获取了
3、将数组应用到shell环境变量
3、将数组应用到shell环境变量(1)
数组赋值:
[root@pps ~]# SEASON=("Srping" "Summer" "Autumn" "Winter")
当你发现赋值错了,也可以立刻从新赋值纠正,如上面的 Spring 被写成 Srping。重新赋值:(原来的值被重写)[root@pps ~]# SEASON=("Spring" "Summer" "Autumn" "Winter")
查看一下环境变量:[root@pps ~]# set | grep SEASONSEASON=([0]="Spring" [1]="Summer" [2]="Autumn" [3]="Winter")
显示整个数组:[root@pps ~]# echo ${SEASON[*]}&&或者 echo ${SEASON[@]}Spring Summer Autumn Winter
显示某一数组元素:[root@pps ~]# echo ${SEASON[3]}Winter
给单个数组元素赋值:[root@pps ~]# SEASON[0]="New_Spring"
再查看一下看数组:[root@pps ~]# echo ${SEASON[*]}New_Spring Summer Autumn Winter
清除指定的单个数组元素:[root@pps ~]# unset SEASON[2]
清除整个数组:[root@pps ~]# unset SEASON
4、将数组应用到shell环境变量(2)&【这个用法不错!给原作者赞一个!】
使用tr命令将文件中的回车转换成空格:[root@pps ~]# cat /etc/shells | tr "\n" " " > /tmp/tmp.file
将文件中内容给数组赋值:(碰到第一个回车符之前的内容)[root@pps ~]# read -a SHELLS < /tmp/tmp.file
查看数组赋值情况:[root@pps ~]# set | grep "SHELLS"SHELLS=([0]="/bin/sh" [1]="/bin/bash" [2]="/sbin/nologin" [3]="/bin/tcsh" [4]="/bin/csh" [5]="/bin/ksh")
后面可以将这个数组环境变量应用到其它的SHELL脚本或者应用程序里了~
阅读(14673) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~
请登录后评论。在shell中可否把ls的输出存进一个数组变量中?-红联Linux系统门户
在shell中可否把ls的输出存进一个数组变量中?
[code]我在网上找到这个:
c=0
for
filelist[$c]=$file
1`
done [/code]但是中间存在这个问题,如果文件名中有空格的话,这个做出的结果是错误的。那么该怎么处理?有其他办法没有?linux awk数组操作详细介绍 - 程默 - 博客园
用awk进行文本处理,少不了就是它的数组处理。那么awk数组有那些特点,一般常见运算又会怎么样呢。我们先看下下面的一些介绍,结合例子我们会讲解下它的不同之处。在 awk 中数组叫做关联数组(associative arrays),因为下标记可以是数也可以是串。awk 中的数组不必提前声明,也不必声明大小。数组元素用 0 或空串来初始化,这根据上下文而定。例如: & 一、定义方法 & 1:可以用数值作数组索引(下标)Tarray[1]=“cheng mo”
Tarray[2]=“800927”
2:可以用字符串作数组索引(下标)Tarray[“first”]=“cheng ”
Tarray[“last”]=”mo”
Tarray[“birth”]=”800927”
使用中 print Tarray[1] 将得到”cheng mo” 而 print Tarray[2] 和 print[“birth”] 都将得到 ”800927” 。
二、数组相关函数
[chengmo@localhost ~]$ awk --versionGNU Awk 3.1.5
使用版本是:3.1以上,不同版本下面函数不一定相同
得到数组长度(length方法使用)
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA),}'4 4
length返回字符串以及数组长度,split进行分割字符串为数组,也会返回分割得到数组长度。
(asort使用):
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}'4
asort对数组进行排序,返回数组长度。
输出数组内容(无序,有序输出):
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'4 test1 it2 is3 a
for…in 输出,因为数组是关联数组,默认是无序的。所以通过for…in 得到是无序的数组。如果需要得到有序数组,需要通过下标获得。
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k&=k++){print k,tA[k];}}' 1 it2 is3 a4 test
注意:数组下标是从1开始,与c数组不一样。
判断键值存在以及删除键值:
一个错误的判断方法:
[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if(tB["c"]!="1"){print "no found";};for(k in tB){print k,tB[k];}}' no founda a1b b1c
以上出现奇怪问题,tB[“c”]没有定义,但是循环时候,发现已经存在该键值,它的值为空,这里需要注意,awk数组是关联数组,只要通过数组引用它的key,就会自动创建改序列.
正确判断方法:
[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";};for(k in tB){print k,tB[k];}}'& a a1b b1
if(key in array) 通过这种方法判断数组中是否包含”key”键值。
删除键值:
[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'&&&&&&&&&&&&&&&&&&&& b b1
delete array[key]可以删除,对应数组key的,序列值。
三、二维数组使用(多维数组使用)
awk的多维数组在本质上是一维数组,更确切一点,awk在存储上并不支持多维数组。awk提供了逻辑上模拟二维数组的访问方式。例 如,array[2,4] = 1这样的访问是允许的。awk使用一个特殊的字符串SUBSEP (\034)作为分割字段,在上面的例子中,关联数组array存储的键值实际上是2\0344。
类似一维数组的成员测试,多维数组可以使用 if ( (i,j) in array)这样的语法,但是下标必须放置在圆括号中。类似一维数组的循环访问,多维数组使用 for ( item in array )这样的语法遍历数组。与一维数组不同的是,多维数组必须使用split()函数来访问单独的下标分量。split ( item, subscr, SUBSEP)
[chengmo@localhost ~]$ awk 'BEGIN{
for(i=1;i&=9;i++){& for(j=1;j&=9;j++)& & {tarr[i,j]=i*j;print i,"*",j,"=",tarr[i,j];& }}}'1 * 1 = 11 * 2 = 21 * 3 = 31 * 4 = 41 * 5 = 51 * 6 = 6
可以通过array[k,k2]引用获得数组内容.
[chengmo@localhost ~]$ awk 'BEGIN{for(i=1;i&=9;i++){& for(j=1;j&=9;j++)& & {tarr[i,j]=i*j;& }}for(m in tarr)&&&&&&&&&&&&& {split(m,tarr2,SUBSEP);print tarr2[1],"*",tarr2[2],"=",tarr[m];}}'
以上是awk对数组的处理相关,希望对大家有用。

我要回帖

更多关于 linuxshell数组 的文章

 

随机推荐