shell数组赋值问题

sh/bash/dash/ksh/zsh等Shell脚本
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

shell数组赋值问题

#1

帖子 vinoca » 2011-09-22 16:41

想把find的每个结果依次填入数组单元中,其结果包含空格,怎么做?
如这种情况: pl=("${pl[@]}" "`find ${dir} -name "*is*"`")
设置IFS经验证还是不行。
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell数组赋值问题

#2

帖子 naturalaw » 2011-09-22 21:09

代码: 全选

unset pl
for i in `find ${dir} -name "*is*"`;do pl=("${pl[@]}" "$i");done
试试 .
  • The eternal law
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell数组赋值问题

#3

帖子 naturalaw » 2011-09-23 2:03

似乎这样也行。

代码: 全选

pl=(`find ${dir} -name "*is*"`)
  • The eternal law
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#4

帖子 vinoca » 2011-09-24 10:19

naturalaw 写了:似乎这样也行。

代码: 全选

pl=(`find ${dir} -name "*is*"`)
谢谢你的回复。
这些也曾试过,文件名有空格还是不行。另外pl中原来是有内容的,如果这样会把原来的内容覆盖掉。
头像
naturalaw
帖子: 1360
注册时间: 2011-09-06 22:04

Re: shell数组赋值问题

#5

帖子 naturalaw » 2011-09-24 11:26

代码: 全选

cd /tmp/test
rm * -rfv
touch "a b" "c d" "e f" "gh"
mkdir ais{1..3}
touch "bis "{1..3}
dir=/tmp/test
echo "the files are"
ls
pl=("a c")
echo -e "old array is\n${pl[@]}"
pl=(${pl[@]} `find ${dir} -name "*is*"`);
echo -e "new array is\n${pl[@]}"
rm * -rf
sh ../test.sh
the files are
a b ais1 ais2 ais3 bis 1 bis 2 bis 3 c d e f gh
old array is
a c
new array is
a c /tmp/test/bis 3 /tmp/test/bis 2 /tmp/test/bis 1 /tmp/test/ais3 /tmp/test/ais2 /tmp/test/ais1
我不知道还有什么问题
  • The eternal law
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#6

帖子 vinoca » 2011-09-24 14:24

找到原因了。
pl=("${pl[@]}" "`find ${dir} -name "*is*"`")
这个写法中多了引号,不可取,这样会把find的整个结果当成一个元素。
用引号原本是考虑了文件名存在空格这种情况,现在看来,除了移除文件名中的空格别无其它两全其美的办法。

关键字:shell 数组 连接
:em32
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: shell数组赋值问题

#7

帖子 fnan » 2011-09-26 22:07

a=(aa bb)
n=${#a[*]}
while read l;do a[$((n++))]=$l;done <<<"$(find -type f)"
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell数组赋值问题

#8

帖子 eexpress » 2011-09-27 9:39

为什么需要数组。
find xxx|while read i; do yyy; done
● 鸣学
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#9

帖子 vinoca » 2011-09-28 10:59

已经解决了。
文件名中有空格会出现很多问题,while试过,同样会出现错误。
最好移除文件名中所有的空格,有如下脚本:

代码: 全选

#!/bin/bash

for i in `find $1` ;do
fnew=`echo $i | tr -d '[:blank:]'`
[ "$fnew" != "$i" ] && echo $fnew &&mv "$i" $fnew
done
需要改进,不能递归,有些情况下会失败(好像目录名及文件名均有空格,情景已无法复原),mv提示找不到文件。欢迎继续讨论 :em02
上次由 vinoca 在 2011-09-28 11:02,总共编辑 1 次。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell数组赋值问题

#10

帖子 eexpress » 2011-09-28 11:01

while read i 是读入行。后续操作使用"$i"。怎么可能还有空格问题。。。。
● 鸣学
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#11

帖子 vinoca » 2011-09-28 11:08

eexpress 写了:while read i 是读入行。后续操作使用"$i"。怎么可能还有空格问题。。。。
是可行的。
但是问题是接下来要这样使用 exec this_array ,最后还是失败。所以说删除空格是最好的办法 :em09
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell数组赋值问题

#12

帖子 eexpress » 2011-09-28 11:12

exec 是指啥?直接说出要求。

你的思维不对的,空格只是一个特例,还有其他符号,会干扰bash的。有些时候,还可能需要使用\'$i\'等不同的写法,处理的。
● 鸣学
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#13

帖子 vinoca » 2011-09-28 11:16

eexpress 写了:exec 是指啥?直接说出要求。

你的思维不对的,空格只是一个特例,还有其他符号,会干扰bash的。有些时候,还可能需要使用\'$i\'等不同的写法,处理的。
将数组的内容作为参数传给一个程序,而参数的解析是用空格分隔参数的。最近做一个调用mplayer播放歌曲的脚本,如此。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: shell数组赋值问题

#14

帖子 eexpress » 2011-09-28 11:26

传过去的时候,"$i"就可以了。一次性传递字符串,可以使用\"或者\'包括每一个项目。
如果接收的是bash脚本,使用$@处理传入的就是,自动分割带空格和特殊字符的参数的。不用操心。

改文件名,比较不是长久之计。一定要这样,你可以使用incron监视目录,进入目录的文件,自动改名,处理掉空格和特殊字符(:|?\/)等。
● 鸣学
头像
vinoca
帖子: 59
注册时间: 2011-03-21 18:30

Re: shell数组赋值问题

#15

帖子 vinoca » 2011-09-28 11:47

eexpress 写了:传过去的时候,"$i"就可以了。一次性传递字符串,可以使用\"或者\'包括每一个项目。
如果接收的是bash脚本,使用$@处理传入的就是,自动分割带空格和特殊字符的参数的。不用操心。

改文件名,比较不是长久之计。一定要这样,你可以使用incron监视目录,进入目录的文件,自动改名,处理掉空格和特殊字符(:|?\/)等。
嗯,刚做了测试,目录中有4个文件:

代码: 全选

类似爱情.mp3  伤不起.mp3  映山红.mp3  雨蝶.ape
然后:

代码: 全选

a=(类似爱情.mp3 "伤不起.mp3 映山红.mp3" 雨蝶.ape)
echo ${a[@]}
echo ${#a[@]}
mplayer ${a[@]}
有3个数组元素,mplayer会正常播放这4个歌曲。引号会被忽略,空格等空白字符是参数分隔的标志。很明显,bash在给数组赋值时把引号剥离了,再传入:

代码: 全选

 a=(类似爱情.mp3 "\"伤不起.mp3 映山红.mp3\"" 雨蝶.ape)
mplayer会将第2个数组元素解析为"伤不起.mp3和映山红.mp3",空格仍然是特殊字符,而引号则成了一般字符。其它程序未做测试。
文件名中空格是*nix操作系统的机制问题,看来确实如此。
回复