我有以下bash脚本:
#!/bin/bash
test=$(find . -name "*.cfg")
echo ${#test[@]}
输出只是1.但是,find返回8个元素,当在循环中使用时,它们的名称会正确显示:
for f in $(find . -name "*.cfg")
do
echo $f
done
如何查看test
数组的大小?谢谢!
答案 0 :(得分:3)
将find
的输出存储到数组中的唯一安全方法是使用-print0
扩展名,而不是POSIX(但GNU find
支持它):
files=()
while IFS= read -r -d '' file; do
files+=( "$file" )
done < <(
find . -name '*.cfg' -print0
)
printf 'There are %d files found.\n' "${#files[@]}"
如果您只想要找到的文件数量,可以使用它(使用-printf
,而不是POSIX但GNU支持):
xfiles=$(find . -name '*.cfg' -printf 'x')
printf 'There are %d files found.\n' "${#xfiles}"
或符合POSIX标准:
xfiles=$(find . -name '*.cfg' -exec printf "%.sx" {} +)
printf 'There are %d files found.\n' "${#xfiles}"
现在Bash≥4可以自行解决这个问题:
shopt -s globstar nullglob
files=( **/*.cfg )
printf 'There are %d files found.\n' "${#files[@]}"
(虽然它可能比find
慢。)
答案 1 :(得分:2)
test
是一个字符串(不是数组)。
你正在使用[@]
,它没有做任何有用的事情,并且正在为你破坏事物。放弃它。
您希望${#test}
获取字符串的长度。如果你想要一个数组,你需要做不同的事情。
您不想要解析/阅读/ for
- 循环/等。通过这种方式输出(对于“奇数”文件名来说是不安全的。)
有关安全执行此操作的方法,请参阅http://mywiki.wooledge.org/BashFAQ/001(具体请参阅有关-print0
的部分)。
答案 2 :(得分:2)
由于您没有使用find
的任何其他功能,我会使用glob来创建数组:
# Bash 4+
shopt -s globstar
test=( **/*.cfg )
globstar
选项启用模式**
,它匹配路径中的0个或更多目录。它允许与目录层次结构进行递归匹配,因此**/*.cfg
将匹配./foo.cfg
,./bar/hello world.cfg
等。每个匹配的文件,无论文件名中是否存在任何特殊字符,都将是作为单个数组条目处理。
如果您需要支持bash
的旧版本,假设您的find
版本支持-print0
或类似内容,则可以使用更复杂的技术。
答案 3 :(得分:-1)
你必须先创建一个数组,试试这个:
test=($(find . -name "*.cfg"))
echo ${#test[@]}