LinuxSir.Org  
| 网站首页 | 注册账号 | 论坛帮助 |

欢迎来到LinuxSir.Org!
您还未登录,请登录后查看论坛,或者点击论坛上方的注册链接注册新账号。


发表新主题 回复
精华主题  
主题工具
旧 04-05-05, 00:48 第 1 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

标题: 关于array中的变量替换? [分享]


有这样一个较复杂的命令, 这里列出其中11个args的array.
代码:
option1=("choice" "-enable") option2=("-c" "120") option3=("-start" "001") option4=("-stop") option5=("-Rule" "rule1 day1:day2") option6=("-interval" "06:33" "13:03") option7=("-t" "name1" "value1") option8=("-e" "event1") option9=("-o" "4") option10=("-h" "1")
对于array的变量替换尝试了多种方法:
代码:
for i in $(seq 10); do #stdout option1 的第一个和第二个element. echo ${option$i[1]} ${option$i[2]} #错误写法. eval echo \$"option"$i; eval echo \$"option"$i[1] #第一个ok,第二个不行. eval echo \$${option"$i"[1]}; eval echo \$${option$i[1]} #报错 #尝试了很多写法,最后试出来了正确的array替换表达式: eval echo \$"{option"$i[0]"}";eval echo \$"{option"$i[1]"}" done
下面的方法列出所有的ARGS:
代码:
j=0 ARGS="" for i in $(seq 10); do j=0 while [ $j -le $(eval echo \$'{#option'$i[@]'}') ]; do NEWARGS=$(eval echo \$'{option'$i[$j]'}') ARGS="$ARGS $NEWARGS" j=$((++j)) done done echo $ARGS
还有什么好的办法, 也请分享. 谢谢!
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 01:38 第 2 帖
KornLee
 
 
 
★☆★☆★☆★  
  注册日期: Nov 2002
  我的住址: LinuxWorld
  帖子: 6,960
  精华: 61
 

your code is very Excellent
  KornLee 当前离线   回复时引用此帖
旧 04-05-05, 02:13 第 3 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

谢谢javalee兄加精. 我在ksh中试for loop的C形式写法,不认. ksh中是不是不能用C型写法呢. 个人感觉shell的C语法形式较简练.







__________________
15" C2D MBP.
有简单的,不用复杂的!看到复杂的,尽量简单化!
Unix/Linux Philosophy: Be small! Be concentrated! One program does one thing and do it perfectly!
∞ years - 宇宙中最后的物质 Proton heat death. 之后,宇宙将以纯能量的形式永远存在。。。一切皆空
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 10:19 第 4 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

嗯,不错。
这其实就是"命令行处理"的应用例子。







__________________
IBOX, a LiveCD distribution based on Gentoo, is fit for newbie.

IBOX brings to you:
- knoppix-style harddisk installation tool, by which you can install Gentoo in 20 minutes.
- hardware auto-configuration. You can run into X desktop directly.
- all-round software set, including OpenOffice, azureus.
- LiveCD-create-tools. Step-by-step, custom a LiveCD yourself with ease.

Any questions and feedbacks is welcome to home_king at 163 dot com
  home_king 当前离线   回复时引用此帖
旧 04-05-05, 12:44 第 5 帖
KornLee
 
 
 
★☆★☆★☆★  
  注册日期: Nov 2002
  我的住址: LinuxWorld
  帖子: 6,960
  精华: 61
 

引用:
最初由 yongjian 发表
谢谢javalee兄加精. 我在ksh中试for loop的C形式写法,不认. ksh中是不是不能用C型写法呢. 个人感觉shell的C语法形式较简练.
我用的pdksh不支持你说的那种写法~~.ksh的版本比较多,目前的版本多是ksh93以后的~~,各个版本的兼容性很差!
  KornLee 当前离线   回复时引用此帖
旧 04-05-05, 22:02 第 6 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

这个方法在Unix中不行! 只能用于Linux bash! (已在AIX上试过)
1. seq cmd在Unix中没有.
2. 替换的语法不一样.
3. Unix上不支持C型语法,所以j=$((++j))不work.
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 22:06 第 7 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

给出Unix上的写法,略有不同:
代码:
for i in 1 2 3 4 5 6 7 8 9 10; do j=0 while [ $j -le $(eval echo '${#option'$i[@]'}') ]; do NEWARGS=$(eval echo '${option'$i[$j]'}') ARGS="$ARGS $NEWARGS" let j=j+1 done done echo $ARGS
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 22:09 第 8 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

哦, 对了. ksh上定义array的方法也不一样. 楼顶帖中的方法是bash的. ksh中是
代码:
set -A arrayname element1 element2 ...
这个javalee兄较熟...
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 22:21 第 9 帖
KornLee
 
 
 
★☆★☆★☆★  
  注册日期: Nov 2002
  我的住址: LinuxWorld
  帖子: 6,960
  精华: 61
 

引用:
最初由 yongjian 发表
这个方法在Unix中不行! 只能用于Linux bash! (已在AIX上试过)
1. seq cmd在Unix中没有.
2. 替换的语法不一样.
3. Unix上不支持C型语法,所以j=$((++j))不work.
咱们是linux论坛,应该以linux为主,
另外,建议兄弟贴的时候注明一下系统环境和shell种类, OK
  KornLee 当前离线   回复时引用此帖
旧 04-05-05, 22:22 第 10 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

yongjian兄,你的方法有点冗余,其实这个数组引用一点都不神秘,掌握了"命令行处理"后,使用eval来构造智能命令行也不难。知其然,更要知其所以然,这才是学习的目的。
ps:老是实践,也说明兄弟对于命令行处理的概念不清晰,把握地不好。
修正如下:
代码:
hk@debian:/etc/init.d$ array1[1]=hihi hk@debian:/etc/init.d$ array1[2]=you hk@debian:/etc/init.d$ num=1 hk@debian:/etc/init.d$ index=2 hk@debian:/etc/init.d$ eval echo '$'{array$num[$index]} you
如精华帖子所言
http://www.linuxsir.org/bbs/showthre...threadid=99465
我分析一下:
1.单引号跳过了前10步处理,于是第一个"$"不变
2.正常地进行$var变量替换,其余普通字符保留,于是,第一次命令行处理结果为eval echo ${array1[2]}
3.eval再次执行一次处理过的命令行,命令处理为echo ${array1[2]}
4.执行命令,结果如上所示例,达到动态引用数组的效果

很佩服兄弟的实践精神,我希望兄弟能再做好一点,在实践的同时,不要忘了上升为理论,这样才达到学习的目的,要学的知识有很多,关键是掌握规律,掌握了规律,学一当十也

此帖于 04-05-05 22:30 被 home_king 编辑.
  home_king 当前离线   回复时引用此帖
旧 04-05-05, 23:47 第 11 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

感谢了! 其实我是看到很多兄弟学习到了方法后应用到了不同的平台上但是发现语法不一样,或是命令不支持,才将不同的系统中的差异写出来的.主要是希望看到这个帖的兄弟不要什么都照搬照套.Linux和Unix在CLI上还是有很多差异的. 以后我都会将代码能够应用的平台和shell注明的.
To 教主: 教主说的是,我以前确实是对变量替换的概念理解的不够深,特别是对array的变量替换. 不过现在我知道了. 其实很简单, 变量替换符${}内是不能再存在变量的. 不论是'$'{array$num[$index]}的写法,还是'${array'$num[$index]'}'的写法, 都是为了esc前10步,将结果交给eval . 当然,教主的写法简单一些.
  yongjian 当前离线   回复时引用此帖
旧 04-05-05, 23:55 第 12 帖
home_king
 
home_king 的头像
 
 
临时退役版主  
  注册日期: Mar 2003
  帖子: 2,759
  精华: 15
 

yongjian兄努力!:2cool
  home_king 当前离线   回复时引用此帖
旧 04-05-06, 00:19 第 13 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

在Linux下bash下还有一种对于简单变量的替换方法, a=b;b=c;echo ${!a},但是只是对于Linux的bash, ksh都不行. array变量好象也是无法应用的.
  yongjian 当前离线   回复时引用此帖
旧 07-11-29, 10:29 第 14 帖
zswlb9999
 
 
 
注册会员  
  注册日期: Jan 2005
  帖子: 740
  精华: 0
 

标题: 其实,这是间接引用在数组上的实现问题


#!/usr/bin/bash
#其实,这是间接引用在数组上的实现问
#我是最近才学习使用SHELL编程。
#在数组方面的间接引用,我一般是这样处理的:
r1="rt"
r2="tt"
ttrt=( "dfgsd" "fdsfds" "sfsf" "eeefds" )
eval tt$r2='${ttrt[@]}' # tttt=( "dfgsd" "fdsfds" "sfsf" "eeefds" )
#生成tt$rt所指的tttt数组
echo "..1.. "${tttt[@]}
i=2
eval tt$r1[$i]="op" # ttrt[2]='"op"
#间接引用tt$rt[$i]所指的数组成员
echo "..2..ttrt[@]="${ttrt[@]}
p="cc"

eval $p'['$i']'=${ttrt[2]}
#间接生成数组 cc[2]=op
echo "..3..cc[2]="${cc[2]} # op
# 输出验证 cc[2]=op
echo "..4..ttrt[2]="${ttrt[2]}
# 执行 ls -l 命令
#输出验证 ttrt[2]=op
echo "..."
ttrt[2]='ls -l'
#ttrt[2] 赋值为命令ls -l
eval $p'['$i']'='${ttrt[2]}' # 注意,用单引号 ' '为好
eval '${'$p'['$i']}' # 执行ls -l 命令
# 执行 ls -l 命令

eval $p'['$i']'=oooppp #'
eval c='${'$p'['$i']}'
# 以上为= 两边的间接引用方法
echo $c
#输出oooppp
# 这是赋值变量的间接引用注意是在= 的左边,在=右边的引用常见到
##这种方法是函数的传递参数是很有用的,我们传一个数组的名给一个变量的名称,就可以#处理液体个数组
exit

#一下是输出
[wu@myhost ~]$ bash tt
..1.. dfgsd fdsfds sfsf eeefds
..2..ttrt[@]=dfgsd fdsfds op eeefds
..3..cc[2]=op
..4..ttrt[2]=op
...
总计 21
drwx------ 3 wu dgc 320 11-27 11:34 Desktop
drwxr-xr-x 3 wu dgc 10040 2007-03-30 abs-3.9.1_cn
drwxr-xr-x 3 root root 72 11-26 16:38 core
drwxr-xr-x 6 wu dgc 3200 11-28 14:41 down
-rw-r--r-- 1 wu dgc 142 11-25 13:45 pp
-rw-r--r-- 1 wu dgc 1615 11-29 10:46 tt
oooppp

注:清楚的表述见 http://www.linuxsir.org/bbs/showthre...428&highlight=

此帖于 08-01-11 11:42 被 zswlb9999 编辑.
  zswlb9999 当前离线   回复时引用此帖
旧 07-12-01, 07:27 第 15 帖
yongjian
 
yongjian 的头像
 
 
★版☆主★  
  注册日期: May 2003
  我的住址: Linux
  帖子: 2,572
  精华: 9
 

引用:
作者: zswlb9999
#!/usr/bin/bash
#其实,这是间接引用在数组上的实现问
#我是最近才学习使用SHELL编程。
#在数组方面的间接引用,我一般是这样处理的:
r1="rt"
r2="tt"
ttrt=( "dfgsd" "fdsfds" "sfsf" "eeefds" )
eval tt$r2='${ttrt[@]}' # tttt=( "dfgsd" "fdsfds" "sfsf" "eeefds" )
#生成tt$rt所指的tttt数组
echo "..1.. "${tttt[@]}
i=2
eval tt$r1[$i]="op" # ttrt[2]='"op"
#间接引用tt$rt[$i]所指的数组成员
echo "..2..ttrt[@]="${ttrt[@]}
p="cc"

eval $p'['$i']'=${ttrt[2]}
#间接生成数组 cc[2]=op
echo "..3..cc[2]="${cc[2]} # op
# 输出验证 cc[2]=op
echo "..4..ttrt[2]="${ttrt[2]}
# 执行 ls -l 命令
#输出验证 ttrt[2]=op
echo "..."
ttrt[2]='ls -l'
#ttrt[2] 赋值为命令ls -l
eval $p'['$i']'='${ttrt[2]}' # 注意,用单引号 ' '为好
eval '${'$p'['$i']}' # 执行ls -l 命令
# 执行 ls -l 命令

eval $p'['$i']'=oooppp #'
eval c='${'$p'['$i']}'
# 以上为= 两边的间接引用方法
echo $c
#输出oooppp
# 这是赋值变量的间接引用注意是在= 的左边,在=右边的引用常见到
##这种方法是函数的传递参数是很有用的,我们传一个数组的名给一个变量的名称,就可以#处理液体个数组
exit

#一下是输出
[wu@myhost ~]$ bash tt
..1.. dfgsd fdsfds sfsf eeefds
..2..ttrt[@]=dfgsd fdsfds op eeefds
..3..cc[2]=op
..4..ttrt[2]=op
...
总计 21
drwx------ 3 wu dgc 320 11-27 11:34 Desktop
drwxr-xr-x 3 wu dgc 10040 2007-03-30 abs-3.9.1_cn
drwxr-xr-x 3 root root 72 11-26 16:38 core
drwxr-xr-x 6 wu dgc 3200 11-28 14:41 down
-rw-r--r-- 1 wu dgc 142 11-25 13:45 pp
-rw-r--r-- 1 wu dgc 1615 11-29 10:46 tt
oooppp
好帖!最喜欢看这种研究帖。eval的确是解决动态替换的利剑。
  yongjian 当前离线   回复时引用此帖
发表新主题 回复


主题工具

发帖规则
您 [不可以] 发表新主题
您 [不可以] 回复主题
您 [不可以] 上传附件
您 [不可以] 编辑您的帖子

已 [启用] BB 代码
已 [启用] 表情符号
已 [启用] IMG 代码
已 [禁用] HTML 代码
[论坛跳转…]


所有时间均为[北京时间]。现在的时间是 12:34


Powered by vBulletin 版本 3.6.8
版权所有 ©2000 - 2010, Jelsoft Enterprises Ltd.
官方中文技术支持: vBulletin 中文
版权所有 ©2002 - 2009, LinuxSir.Org