运行bash命令
myarray="(`find -type d -printf '%dt%Pn' | cut -f2`)"
在我目前的工作目录中,然后输出MyArray的内容,
tLen=${#myarray[@]}
for (( i=0; i<${tLen}; i++ ))
do
echo "${myarray[$i]}"
done
带有空白的目录名称被拆分。即,目录名称"我的税收文件"中的白色空间不会自动逃脱,最终成为数组中的三个条目,"我的"税"文档",而不是一个名称。但是运行
find -type d -printf '%dt%Pn' | cut -f2
命令行的工作正常。在将查找的输出分配到数组中时,我该如何防止单词分裂?
正确地做
您不能在任意文件名之后安全地使用newline作为尾随定界符:文件名可以包含newlines 。
以下使用明确的定界符和与所有可能的文件名正确使用的read
机制:
myarray=( )
while IFS= read -r -d $'t' depth && IFS= read -r -d '' filename; do
printf 'Found filename %q at depth %dn' "$filename" "$depth" >&2
myarray+=( "$filename" )
done < <(find . -type d -printf '%dt%P ')
# and to demonstrate reading from the array:
echo "Reiterating that list of filenames:" >&2
printf -- '- %qn' "${myarray[@]}"
请注意,我们正在两次调用read
-一旦阅读深度之后的第一个选项卡,然后读取到以下NUL。一个人可能几乎可以通过IFS=$'t' read -r -d '' depth filename
获得这种效果,但是文件名中的领先和尾巴可能会丢失。
参考:
- 使用查找
- bashfaq#1
关于问题出了什么
-
find -type d -printf '%dt%Pn' | cut -f2
首先不会创建正确的文件名列表。尝试使用touch $'footbarnbaztqux'
创建文件,以在这里有一个特别有趣的时光(文件名中的字面新线将由%P
格式指定器发射,从而导致baz
处于该位置,否则包含深度整数,而qux
则显示为显示为看起来像一个完全独立的文件名。 - 默认情况下,空格和选项卡都是
IFS
的一部分,因此都用于字符串切割。 语法
foo="(`...`)"
...实际上根本没有创建一个数组;它创建A String ,以
(
为第一个字符开始,并以)
结束。- 字符串拆分运行Glob Explightion结合使用,因此,如果您有一个名为
touch *
的文件,该文件将被当前目录中的文件列表替换(从而导致其他名称表示为 (。