此脚本应将文件夹存储在fvar2中的目录中folder1/ folder2/ folder3/
然后使用“sed”命令在fvar1中作为folder1 folder2 folder3
回显。
最后它应该回应新数组fvar1
这是错误
./test.sh: line 18: syntax error near unexpected token ``echo "${fvar2[svar3]}" | sed 's#/##g'`'
./test.sh: line 18: `{fvar1[svar4]}=(`echo "${fvar2[svar3]}" | sed 's#/##g'`)'
这是脚本
#!/bin/bash
fvar2=(*/)
svar3=0
svar4=0
while true
do
{fvar1[svar4]}=(`echo "${fvar2[svar3]}" | sed 's#/##g'`)
svar3=`expr $svar3 + 1`
svar4=`expr $svar4 + 1`
echo "${fvar1[svar4]}"
done
答案 0 :(得分:2)
正确的bash方式:
#!/bin/bash
# When using globs, always use either nullglob or failglob
shopt -s nullglob
# define your array fvar2
declare -a fvar2=( */ )
# Remove the trailing slash in each field of fvar2, and make an array fvar1 of it
declare -a fvar1=( "${fvar2[@]%/}" )
# Print each field of array fvar2, one field per line
printf '%s\n' "${fvar1[@]}"
对于带有趣符号(空格,换行符等)的文件名,这是100%安全和防弹。
现在让我稍微扩展一下这个答案,向您展示如何使用更复杂的处理从另一个构建数组。通常,可以使用Shell Parameter Expansions完成简单的处理。但是,如果这还不够,例如,您希望仅保留长度为4的子串,从数组array1
中每个字段的偏移量7开始。解决方案
declare -a array2=( "${array1[@]:7:4}" )
将无效,因为这将占用array1
的字段7到11,因为您将在我上面给出的链接中读到。在这里,您确实需要遍历array1
,进行处理,然后在array2
上推送。这就是你要做的:
# empty and initialize array2
declare -a array2=()
for i in "${array2[@]}"; do
array2+=( "${i:7:4}" )
done
+=
运算符将连接lhs和rhs的数组,将结果放在lhs的数组上。看:
$ declare -a array1=( banana{00..10}gorilla )
$ printf '%s\n' "${array2[@]}"
banana00gorilla
banana01gorilla
banana02gorilla
banana03gorilla
banana04gorilla
banana05gorilla
banana06gorilla
banana07gorilla
banana08gorilla
banana09gorilla
banana10gorilla
$ declare -a array2=()
$ for i in "${array1[@]}"; do array2+=( "${i:7:4}" ); done
$ printf '%s\n' "${array2[@]}"
0gor
1gor
2gor
3gor
4gor
5gor
6gor
7gor
8gor
9gor
0gor
shopt -s nullglob
当使用bash的globs时,总是使用shopt -s nullglob
或shopt -s failglob
你真的想要一个健壮的脚本。为什么?看:
$ shopt -u nullglob failglob # unsetting nullglob and failglob
$ echo there_are_no_files_matching_this_glob_in_this_directory_*
there_are_no_files_matching_this_glob_in_this_directory_*
如您所见,当nullglob和failglob未设置时,如果没有globbing匹配,bash会将glob扩展为自身,逐字逐句。这可能会导致脚本内部出现可怕的内容,例如,如果您想通过将.txt
添加到banana
来重命名所有以.txt
结尾的文件,那么您可以这样做...但是如果没有目录中以$ shopt -u nullglob failglob
$ for i in *.txt; do mv "$i" "banana$i.txt"; done
mv: cannot stat `*.txt': No such file or directory
$ # oh dear :(
结尾的文件?
:(
是的,哦,亲爱的nullglob
,因为你在没有控制其参数的情况下运行命令......这可能是危险的。
现在,如果你打开:)
,如果没有匹配,那么glob将扩展为空! $ shopt -s nullglob; shopt -u failglob
$ for i in *.txt; do mv "$i" "banana$i.txt"; done
$ # Oh... nothing happened, great!
。看:
failglob
或者,如果你打开$ shopt -s failglob; shopt -u nullglob
$ for i in *.txt; do mv "$i" "banana$i.txt"; done
bash: no match: *.txt
$ # Good :)
,如果没有匹配,bash会引发错误:
$ shopt -s nullglob failglob
$ for i in *.txt; do mv "$i" "banana$i.txt"; done
bash: no match: *.txt
$ # Good :)
并且循环永远不会被执行(这很好!你不想在不控制其参数的情况下运行命令)。
如果你打开两个怎么办?
failglob
哦,$ # I'm in a directory with no subdirs
$ # I'm unsetting nullglob and failglob
$ shopt -u nullglob failglob
$ array=( */ )
$ declare -p array
declare -a array='([0]="*/")
$ # Oh dear, my array contains */ verbatim
$ # now, let's set nullglob
$ shopt -s nullglob
$ array=( */ )
$ declare -p array
declare -a array='()'
$ # Now array is truly empty! :)
$ # How about failglob?
$ shopt -u nullglob; shopt -s failglob
$ # You'll see the failure in $? look:
$ echo $?
0
$ # all is good about $?
$ array=( */ )
bash: no match: */
$ echo $?
1
$ # :)
似乎赢了。
在你的情况下,如果没有目录,我想你希望你的数组真的是空的。看:
failglob
但是使用$ declare -a array=( some junk in my array )
$ declare -p array
declare -a array='([0]="some" [1]="junk" [2]="in" [3]="my" [4]="array")'
$ shopt -u nullglob; shopt -s failglob
$ array=( */ )
bash: no match: */
$ declare -p array
declare -a array='([0]="some" [1]="junk" [2]="in" [3]="my" [4]="array")'
$ # Ok, got it! :)
,您的数组将不会重置:
{{1}}