BASH数组中包含空格
我想在我的相机的文件名的bash-shell中构造一个数组:
FILES=(2011-09-04 21.43.02.jpg 2011-09-05 10.23.14.jpg 2011-09-09 12.31.16.jpg 2011-09-11 08.43.12.jpg)
正如你所看到的,每个文件名的中间都有一个空格。
我已经尝试用引号将每个名字包装起来,并用反斜杠将空间转义出来,两者都不起作用。
当我尝试访问数组元素时,它将继续将空间视为元素分隔符。
我怎样才能正确捕捉名称内的空间的文件名?
我认为这个问题可能部分与你如何访问元素有关。 如果我for elem in $FILES
做一个简单for elem in $FILES
,我遇到同样的问题。 但是,如果我通过它的索引访问数组,如果这样,它可以工作,如果我用数字或转义添加元素:
for ((i = 0; i < ${#FILES[@]}; i++)) do echo "${FILES[$i]}" done
$FILES
的这些声明中的任何一个都应该工作:
FILES=(2011-09-04\ 21.43.02.jpg 2011-09-05\ 10.23.14.jpg 2011-09-09\ 12.31.16.jpg 2011-09-11\ 08.43.12.jpg)
要么
FILES=("2011-09-04 21.43.02.jpg" "2011-09-05 10.23.14.jpg" "2011-09-09 12.31.16.jpg" "2011-09-11 08.43.12.jpg")
要么
FILES[0]="2011-09-04 21.43.02.jpg" FILES[1]="2011-09-05 10.23.14.jpg" FILES[2]="2011-09-09 12.31.16.jpg" FILES[3]="2011-09-11 08.43.12.jpg"
访问数组项目的方式肯定有问题。 这是如何完成的:
for elem in "${files[@]}" ...
从bash的manpage :
数组中的任何元素都可以使用$ {name [subscript]}引用。 …如果下标是@或*,则该单词扩展为名称的所有成员。 这些下标仅在双引号出现在单引号内时才有所不同。 如果单词是双引号, $ {name [*]}将扩展为单个单词,每个数组成员的值由IFS特殊variables的第一个字符分隔, $ {name [@]}将名字到一个单独的词 。
当然,访问单个成员时也应该使用双引号
cp "${files[0]}" /tmp
您需要使用IFS以空格作为元素分隔符。
FILES=("2011-09-04 21.43.02.jpg" "2011-09-05 10.23.14.jpg" "2011-09-09 12.31.16.jpg" "2011-09-11 08.43.12.jpg") IFS="" for jpg in ${FILES[*]} do echo "${jpg}" done
如果你想分开的基础上。 那么只要做IFS =“。” 希望它可以帮助你:)
我同意其他人的看法,那就是如何访问这些问题。 引用数组赋值中的文件名是正确的:
FILES=( "2011-09-04 21.43.02.jpg" "2011-09-05 10.23.14.jpg" "2011-09-09 12.31.16.jpg" "2011-09-11 08.43.12.jpg" ) for f in "${FILES[@]}" do echo "$f" done
在任何forms的"${FILES[@]}"
数组周围使用双引号将数组分割成每个数组元素的一个字。 除此之外,它不会做任何分词。
使用"${FILES[*]}"
也有一个特殊的含义,但它将数组元素与$ IFS的第一个字符连接起来,产生一个单词,这可能不是你想要的。
使用裸${array[@]}
或${array[*]}
会将扩展的结果进一步分词,所以最终会以空格(以及$IFS
其他任何内容)每个数组元素的一个单词。
使用C风格for循环也很好,并避免担心分词,如果你不清楚:
for (( i = 0; i < ${#FILES[@]}; i++ )) do echo "${FILES[$i]}" done
逃逸作品
#!/bin/bash FILES=(2011-09-04\ 21.43.02.jpg 2011-09-05\ 10.23.14.jpg 2011-09-09\ 12.31.16.jpg 2011-09-11\ 08.43.12.jpg) echo ${FILES[0]} echo ${FILES[1]} echo ${FILES[2]} echo ${FILES[3]}
输出:
$ ./test.sh 2011-09-04 21.43.02.jpg 2011-09-05 10.23.14.jpg 2011-09-09 12.31.16.jpg 2011-09-11 08.43.12.jpg
引用string也会产生相同的输出。
不完全是对原始问题的引用/转义问题的一个答案,但可能对于op来说实际上更有用:
unset FILES for f in 2011-*.jpg; do FILES+=("$f"); done echo "${FILES[@]}"
当然,expression必须被采纳到特定的要求(例如, *.jpg
为全部或2001-09-11*.jpg
仅为某一天的图片)。
另一种解决scheme是使用“while”循环代替“for”循环:
index=0 while [ ${index} -lt ${#Array[@]} ] do echo ${Array[${index}]} index=$(( $index + 1 )) done