在没有分词的情况下分配find的输出

时间:2017-06-01 20:59:34

标签: arrays bash find

运行bash命令时

myarray="(`find -type d -printf '%d\t%P\n' | cut -f2`)" 

在我目前的工作目录上,然后输出myarray的内容,

tLen=${#myarray[@]}

for (( i=0; i<${tLen}; i++ ))
do
        echo "${myarray[$i]}"
done

带有空格的目录名称将被拆分。即目录名称中的空格&#39;我的税务文件&#39;不会自动转义并最终成为阵列中的三个条目,“我的”#39; &#39;税&#39; &#39;文件&#39;而不只是一个名字。无论如何运行

find -type d -printf '%d\t%P\n' | cut -f2 

从命令行工作正常。将find的输出分配给数组时,如何防止分词?

1 个答案:

答案 0 :(得分:3)

正确行事

在任意文件名后,您无法安全地使用换行符作为尾随分隔符:文件名可以包含换行符

以下使用明确的分隔符和read机制,可以正常使用所有可能的文件名:

myarray=( )
while IFS= read -r -d $'\t' depth && IFS= read -r -d '' filename; do
  printf 'Found filename %q at depth %d\n' "$filename" "$depth" >&2
  myarray+=( "$filename" )
done < <(find . -type d -printf '%d\t%P\0')

# and to demonstrate reading from the array:
echo "Reiterating that list of filenames:" >&2
printf -- '- %q\n' "${myarray[@]}"

请注意,我们正在调用read两次 - 一次读取深度后的第一个选项卡,另一个读取以下NUL。人们可以使用IFS=$'\t' read -r -d '' depth filename 几乎这个效果,但文件名中的前导和尾随标签可能会丢失。

参考文献:

On What Wntong

  • find -type d -printf '%d\t%P\n' | cut -f2首先没有创建正确的文件名列表。尝试使用touch $'foo\tbar\nbaz\tqux'创建一个文件,以便在此处获得特别有趣的时间(文件名中的文字换行符将由%P格式说明符发出,导致baz位于其他位置深度整数,qux显示为看起来像完全独立的文件名的一部分。
  • 默认情况下,空格和制表符都是IFS的一部分,因此都用于字符串拆分。
  • 语法

    foo="(`...`)"
    

    ...实际上并没有创建数组;它创建一个字符串,以(作为第一个字符,以)结尾。

  • 字符串拆分一起运行glob扩展,所以如果你有一个名为touch *的文件,它将替换为当前目录中的文件列表(从而导致其他名称被表示为两次< / em>的)。